以下代码无法在 Visual C++ 2005 中编译。
class SomeClass {
public: boost::function<void()> func;
SomeClass(boost::function<void()> &func): func(func) { }
};
void someFunc() {
std::cout << "someFunc" << std::endl;
}
int main() {
SomeClass sc(boost::function<void()>(&someFunc));
sc.func(); // error C2228: left of '.func' must have class/struct/union
return 0;
}
如果我在 SomeClass 构造函数的参数周围加上括号,或者在参数列表之外构造 boost::function 对象,它可以正常编译。
SomeClass sc((boost::function<void()>(&someFunc)));
// or
boost::function<void()> f(&someFunc);
SomeClass sc(f);
之前的代码有什么问题?
最佳答案
它是一个函数的函数声明,它引用了一个 boost:function <void()>
。并返回 SomeClass
.您可以记住以下规则,事实证明它适用于许多其他此类消歧案例。您可以在 8.2
部分找到这些案例的描述。 C++ 标准。
Any construct that could possibly be a declaration will be taken as a declaration
也就是说,下面会被当作参数声明,括号多余
boost::function<void()>(&someFunc)
如果你去掉括号,这将变得清晰
boost::function<void()> &someFunc
因此,整个声明将不再声明一个对象,而是一个函数
SomeClass sc(boost::function<void()> &someFunc);
要修复它,请使用转换符号
SomeClass sc((boost::function<void()>)&someFunc);
或者像您一样在整个表达式周围加上括号。
这是来自 8.2
的所有荣耀标准:
The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in 6.8 can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in 6.8, the resolution is to consider any construct that could possibly be a declaration a declaration. [Note: a declaration can be explicitly disambiguated by a nonfunction-style cast, by a = to indicate initialization or by removing the redundant parentheses around the parameter name. ]
请注意,为了控制优先级,您可以在任何地方引入括号,如下所示
int (((((((a))))))) = 3;
int (*(pa)) = &a;
关于c++ - 在构造函数参数列表中构造 boost::function 对象时出现错误 C2228,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/992717/