绑定make_unique时出错

chi*_*ili 2 c++ unique-ptr stdbind c++11

我使用的是有麻烦std::bindstd::make_unique.

我有一个对象,其构造函数我传递工厂函数来std::unique_ptr生成另一个类类型的对象.

使用VS2013,这有效:

Tester tester( 
    [](){return std::make_unique<AlphaBetaSingleThreadSSE>( 0,7 ); },
    [](){return std::make_unique<AlphaBetaSingleThread>( 0,7 ); },
    20 );
Run Code Online (Sandbox Code Playgroud)

这给了我编译错误:

Tester tester( 
    std::bind( std::make_unique<AlphaBetaSingleThreadSSE>,0,7 ),
    std::bind( std::make_unique<AlphaBetaSingleThread>,0,7 ),
    20 );
Run Code Online (Sandbox Code Playgroud)

错误消息说明:

错误C2512:'AlphaBetaSingleThread':没有合适的默认构造函数可用

错误C2512:'AlphaBetaSingleThreadSSE':没有合适的默认构造函数可用

为什么这种std::bind方法失败了?

Pio*_*cki 5

std::make_unique 定义如下:

§20.8.1.4[unique.ptr.create]

template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
Run Code Online (Sandbox Code Playgroud)

1 备注:除非T不是数组,否则此函数不应参与重载决策.

2 返回:unique_ptr<T>(new T(std::forward<Args>(args)...)).

通过显式实例化此函数模板,std::make_unique<AlphaBetaSingleThreadSSE>最终得到以下特化:

std::unique_ptr<AlphaBetaSingleThreadSSE> make_unique()
{
    return std::unique_ptr<AlphaBetaSingleThreadSSE>(new AlphaBetaSingleThreadSSE());
}
Run Code Online (Sandbox Code Playgroud)

也就是说,它将不再允许您传递将转发给构造函数的其他参数,AlphaBetaSingleThreadSSE而是尝试使用默认构造函数AlphaBetaSingleThreadSSE(错误消息状态不存在).

您可以通过指定类型模板参数来解决此问题Args:

std::make_unique<AlphaBetaSingleThreadSSE, const int&, const int&>
Run Code Online (Sandbox Code Playgroud)

但是你不会从完美转发中受益,而且这不是一个便携式解决方案.一个更好的解决方案是留下一个lambda.

  • "更好的解决方案是留下一个lambda." - 实际上,回答了90%以上的`std :: bind`问题. (2认同)