为什么匿名对象有时需要默认构造函数?

时间:2014-07-08 01:43:05

标签: c++ most-vexing-parse

如果我编写以下程序,它可以正常工作:

struct Foo {
    Foo (std::string x) { std::cout << x << std::endl; }
};

int main () { Foo("hello, world"); }

但是,如果我编写一个稍微不同的程序,我会收到编译错误:

struct Foo {
    Foo (std::string x) { std::cout << x << std::endl; }
};

std::string x("hello, world");

int main () { Foo(x); }

错误是:

  

prog.cc: In function 'int main()': {
{1}}

The complete error can be seen on IDEONE.

为什么第二个程序而不是第一个程序出错?

3 个答案:

答案 0 :(得分:12)

您已声明类型为x

的变量Foo
struct Foo {
    Foo(){}
    Foo (std::string x) { std::cout << x << std::endl; }
    void test(){ std::cout << "test" << std::endl; };
};

std::string x("hello, world");

int main () { Foo(x); x.test(); }

print "test"


您想要的是使用统一初始化语法Foo{x}

struct Foo {
    Foo (std::string x) { std::cout << x << std::endl; }
};

std::string x("hello, world");

int main () { Foo{x}; }

print "hello, world"

答案 1 :(得分:8)

Foo(x);表示与Foo x;相同。您可以将冗余括号添加到变量名称中。

所以你需要默认的构造函数,因为这是创建一个变量x,没有参数传递给构造函数。

您可以通过在C ++ 11中执行Foo{x};来解决此问题。

解析规则是,如果某些内容可能是有效的声明和有效的非声明语句,那么它实际上是一个声明。另请参阅most vexing parse

答案 2 :(得分:-1)

我完全赞同上述解决方案。虽然这仍然有效:

struct Foo {
    Foo (string x) 
    { 
        cout << x << endl; 
    }
};


int main () 
{ 
    string x = "hello, world";
    Foo * abc = new Foo(x); 
    return 0;
}