在构造函数参数列表中构造 boost::function 对象时出现错误 C2228
下面的代码无法在 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);
前面的代码有什么问题?
The code below does not compile in 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;
}
If I put parentheses around the argument to the SomeClass constructor or constructs the boost::function object outside the argument list it compiles fine.
SomeClass sc((boost::function<void()>(&someFunc)));
// or
boost::function<void()> f(&someFunc);
SomeClass sc(f);
What is the problem with the previous code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它是一个函数的函数声明,该函数引用
boost:function
并返回SomeClass
。 您可以记住以下规则,该规则适用于许多其他此类消歧案例。 您可以在 C++ 标准的8.2
部分中找到这些情况的描述。这意味着,以下内容将被视为参数声明,带有多余的括号
如果删除括号,这将变得清晰
因此,整个声明将不再声明一个对象,但一个函数
要修复它,请使用强制转换符号
或在整个表达式周围放置括号,就像您所做的那样。
以下是
8.2
中的标准:请注意,为了控制优先级,您可以在任何地方引入括号,如下所示
It's a function declaration for a function taking a reference to a
boost:function <void()>
and returning aSomeClass
. You can memorize the following rule, which turns out to apply to many other such disambiguation cases. You can find descriptions of these cases in section8.2
of the C++ Standard.That means, the following will be taken as a parameter declaration, with superfluous parentheses
If you remove the parentheses, this will become clear
And thus, the whole declaration will not anymore declare an object, but a function
To fix it, use the cast-notation
Or put parentheses around the whole expression, like you did.
Here is the Standard in all its glory from
8.2
:Note that for controlling precedence, you are allowed to introduce parentheses just about anywhere, like in the following
这被称为“C++ 最令人烦恼的解析”(摘自 Scott 所著的一本书迈耶斯称之为有效的 STL)。
正如上面的回答,编译器更喜欢将有问题的行解释为函数声明。
This is known as "C++'s Most Vexing Parse" (from a book by Scott Meyers called Effective STL).
As answered above, the compiler prefers to interpret the problematic line as a function declaration.