C ++函数定义和变量声明不匹配?

时间:2017-09-14 12:13:48

标签: c++ most-vexing-parse

考虑这个非常简单的代码:

#include <memory>

class Foo
{
public:
    Foo() {};
};

class Bar
{
public:
    Bar( const std::shared_ptr<Foo>& foo ) {}
}; 

int main()
{
    Foo* foo = new Foo;
    Bar bar( std::shared_ptr<Foo>( foo ) );
    return 0;
}

为什么Visual Studio报告

warning C4930: 'Bar bar(std::shared_ptr<Foo>)': prototyped function not called (was a variable definition intended?)

并且没有创建bar个对象...如何将此行Bar bar( std::shared_ptr<Foo>( foo ) );解释为函数定义?

我检查了Do the parentheses after the type name make a difference with new?C++: warning: C4930: prototyped function not called (was a variable definition intended?),但我觉得我的问题不同,因为我没有使用语法Foo()Bar()

编辑:请注意,它成功编译:

Foo* foo = new Foo;
std::shared_ptr<Foo> fooPtr( foo );
Bar bar( fooPtr );

1 个答案:

答案 0 :(得分:14)

此问题与C++'s most vexing parse有关。声明:

Bar bar( std::shared_ptr<Foo>( foo ) );

声明一个名为bar的函数,它返回Bar并接受foo类型为std::shared_ptr<Foo>的参数。

最里面的括号没有效果。就好像你会写下以下内容一样:

Bar bar( std::shared_ptr<Foo> foo);

假设C ++ 11(因为您已经在使用std::shared_ptr),您可以使用大括号语法而不是括号

Bar bar(std::shared_ptr<Foo>{foo});

这实际上会构造一个类型为bar的对象Bar,因为由于大括号,上面的语句不能被解释为声明。