Мой вопрос похож на этот ответ , но с одной большой разницей.
Если я попытаюсь скомпилировать следующее,
void test(string x){
int x = 5;
cout << x << endl;
}
Я получаю ожидаемое предупреждение:
In function ‘void test(std::__cxx11::string)’:
error: declaration of ‘int x’ shadows a parameter
int x = 5;
^
Теперь, чтобы добраться до сути моего вопроса; если у меня есть тип с оператором вызова функции, как показано ниже:
struct foo{
string bar;
foo(const string& bar) : bar(bar) { }
void operator()(){
cout << "my bar is \"" << bar << '"' << endl;
}
};
Я могу создать временный объект и вызвать его оператор ()
с помощью foo("this will print")();
или foo{"this will also print"}();
Если я попытаюсь сделать следующее, я получу ошибку компилятора, которая является ожидаемой и может быть объяснена постом, на который я ссылаюсь выше.
void redeclaration_error(){
string x("lol");
foo(x)();
}
Однако, здесь все странно:
void hmm1(string str){
foo(str)();
}
void hmm2(string str){
foo{str}();
}
Хотя hmm2
будет выводить аргумент при вызове, hmm1
абсолютно ничего не сделает. Это ожидается, так как тело hmm1
не делает ничего, кроме объявления str
типа foo
. Однако в области hmm1
, str
уже объявлено как тип string
из параметра функции, так почему это не приводит к ошибке компилятора, такой как error: declaration of ‘foo str‘ shadows a parameter
?
Я понимаю, что компилятор интерпретирует foo(str)();
как объявление, и такие строки, как foo(str).operator()();
и (foo(str))();
будут интерпретироваться как создание временного объекта foo и вызов их оператора вызова функции, но почему это нормально? объявить переменную с тем же именем, что и параметр в этом случае?
Вот и ссылка Ideone, где я играл с этим.