【发布时间】:2016-04-28 12:45:56
【问题描述】:
我正在做一些模板元编程,我想实现一个通用克隆函数,该函数通过 SFINAE(替换失败不是错误)根据表达式的有效性选择一种克隆方法。
功能
make_unique<T>( std::forward<Args>(args)... )
相当于:
unique_ptr<T>(new T(std::forward<Args>(args)...))
这是否意味着下面的代码
template <typename T>
auto my_clone( const T & t ) -> decltype( std::make_unique<T>(t) )
{
return std::make_unique<T>(t);
}
应该完全等价于
template <typename T>
auto my_clone( const T & t ) -> decltype( std::unique_ptr<T>( new T(t) ) )
{
return std::unique_ptr<T>( new T(t) );
}
即使我有函数my_clone 的其他重载?换句话说:是std::make_unique()SFINAE-friendly?
如果T 不是可复制构造,则由于 SFINAE,后一个代码将不会参与重载决议。
下面是一个在 GCC 5.3 上编译失败且 C++14 开启的小例子:
#include <memory>
// It does **not** work with this snippet:
template <typename T>
auto my_clone( const T & t ) -> decltype( std::make_unique<T>( t ) )
{
return std::make_unique<T>( t );
}
/* // But it works with this snippet instead:
template <typename T>
auto my_clone( const T & t ) -> decltype( std::unique_ptr<T>( new T(t) ) )
{
return std::unique_ptr<T>( new T(t) );
}*/
// This is another overload for testing purposes.
template <typename T>
auto my_clone( const T & t ) -> decltype(t.clone())
{
return t.clone();
}
class X
{
public:
X() = default;
auto clone() const
{
return std::unique_ptr<X>( new X(*this) );
}
private:
X( const X & ) = default;
};
int main()
{
// The following line produces the compiler error:
// "call to 'my_clone' is ambiguous"
const auto x_ptr = my_clone( X() );
}
【问题讨论】:
-
标准不保证,请勿依赖。
-
@Holt 标准不能保证什么?在 [unique.ptr.create] 它声明
make_unique返回:unique_ptr<T>(new T(std::forward<Args>(args)...)). -
@NathanOliver 是,但标准不保证如果
T不能使用Args&&...构造,则std::make_unique(Args&&...)不应该存在。 -
@Holt 好吧。我只是不确定你在说什么。
-
在您的情况下,您可以改用
std::is_copy_constructible特征。
标签: c++ c++11 unique-ptr sfinae