我在使用中遇到了麻烦 std::bind
与 std::make_unique
.
我有一个对象,我向它的构造函数传递工厂函数,用于制作 std::unique_ptr
的对象。
使用VS2013,这可以工作。
Tester tester(
[](){return std::make_unique<AlphaBetaSingleThreadSSE>( 0,7 ); },
[](){return std::make_unique<AlphaBetaSingleThread>( 0,7 ); },
20 );
这给了我编译错误。
Tester tester(
std::bind( std::make_unique<AlphaBetaSingleThreadSSE>,0,7 ),
std::bind( std::make_unique<AlphaBetaSingleThread>,0,7 ),
20 );
错误信息显示: 错误C2512: 'AlphaBetaSingleThread' : 没有合适的默认构造函数
错误C2512: 'AlphaBetaSingleThread' : 没有合适的默认构造函数可用
错误 C2512:'AlphaBetaSingleThreadSSE':没有合适的默认构造函数。
为什么 std::bind
方法失败?
std::make_unique
的定义如下。
§ 20.8.1.4 [unique.ptr.create]
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
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());
}
就是说,它不会再让你传递额外的参数,而这些参数会被转发给构造函数 AlphaBetaSingleThreadSSE
的缺省构造函数,而会尝试使用默认的 AlphaBetaSingleThreadSSE
(正如错误信息所说,它并不存在)。
你可以通过指定模板类型参数来解决这个问题。Args
:
std::make_unique<AlphaBetaSingleThreadSSE, const int&, const int&>
但这样一来,你就无法从完美转发中获益,而且这也不是一个便携的解决方案。一个更好的解决方案是继续使用lambda。