我不明白以下问题。
class InnerBox
{
public:
InnerBox() : mContents(123) { };
private:
int mContents;
};
class Box
{
public:
Box(const InnerBox& innerBox) : mInnerBox(innerBox) { };
private:
InnerBox mInnerBox;
};
void SomeFunction(const Box& box)
{
return;
}
int main()
{
Box box(InnerBox()); // !!PROBLEM!! Doesn't work: compiler thinks this is a function declaration
SomeFunction(box); // Error, cannot convert 'function pointer type' to const Box&
return 0;
}
完整的错误消息是(Visual Studio 2010)
error C2664: 'SomeFunction' : cannot convert parameter 1 from 'Box (__cdecl *)(InnerBox (__cdecl *)(void))' to 'const Box &'
修复很简单:
int main()
{
InnerBox innerBox;
Box box(innerBox);
SomeFunction(box);
return 0;
}
这是MSVC特有的问题,如果没有,有人可以解释这种语言的怪癖阻止我调用Box box(InnerBox());
吗?
答案 0 :(得分:5)
你需要把它写成:
Box box((InnerBox()));
或
Box box{InnerBox()};
这不是MSVC特定的问题。 C ++中的规则是考虑任何可能是声明声明的构造。
如果没有附加括号,代码将声明一个名为box
的函数,该函数返回Box
,其单个参数是一个指向函数的指针,该函数不带参数并返回InnerBox
。 (是 - InnerBox()
实际上在函数参数中使用时声明了一个指向函数(未命名)的指针(这类似于Box[]
在使用时实际声明指向Box
的方式作为函数参数))。
答案 1 :(得分:5)
对于名为'box'的函数,原始like被解析为函数声明(不是 definition ),该函数返回Box并将函数指针作为参数返回InnerBox并且不带参数InnerBox (*)()
。有关最令人烦恼的解析问题的详细说明,请参阅this。
您可以使用其他括号Box box((InnerBox()));
明确区分对象构造。或者作为一种稍微更清晰的替代方法,您可以使用新的C ++ 11对象构造语法:
Box box{InnerBox()};
答案 2 :(得分:4)
这是一个特定于MSVC的问题,如果没有,有人可以解释这种语言的怪癖阻止我调用Box框(InnerBox()); ?
完成其他答案:
这称为most vexing parse。这对编译器来说不是问题。它基本上是一个解析规范,它表示可以作为声明处理的任何内容都被视为声明。
在您的情况下,您可以使用
进行修复Box box((InnerBox()));