我的问题与这个已解答的问题类似,但有一个重要的区别。
如果我尝试编译以下代码:
现在来看我的问题的核心; 如果我有一个类型,其中包含如下所示的函数调用运算符:
然而,在这里事情变得奇怪:
虽然调用时,
我理解编译器将
这里有一个我玩弄此事的Ideone链接。
如果我尝试编译以下代码:
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链接。