Is std::make_unique SFINAE-friendly?
Is std::make_unique SFINAE-friendly?
我正在进行一些模板元编程,我想实现一个通用的克隆函数,该函数通过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) );
}
即使我有函数CCD_ 1的其他重载?换句话说:std::make_unique()
SFINAE友好吗?
如果T
是而不是可复制构造的,则由于SFINAE,后一个代码将不会参与过载解决。
以下是一个在开启C++14的情况下无法在GCC 5.3上编译的小示例:
#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() );
}
标准仅保证:
template <class T, class... Args> unique_ptr<T> std::make_unique(Args&&... args);
必须返回unique_ptr<T>(new T(std::forward<Args>(args)...))
,它不能保证make_unique
函数只在T
可以使用Args...
构造的情况下存在,因此它对SFINAE不友好(根据标准),因此您不能依赖它。
标准中唯一提到make_unique
:的部分
&教派;20.8.1.4[unique.ptr.create]:
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
- 备注:除非T不是数组,否则此函数不应参与过载解析
- 返回:
unique_ptr<T>(new T(std::forward<Args>(args)...))
在您的情况下,您可能希望使用带有my_clone
0的版本,或者使用is_copy_constructible
使您的my_clone
SFINAE友好(@Yakk,@Jarod42),例如:
template <typename T,
typename = std::enable_if_t<std::is_copy_constructible<T>::value>>
auto my_clone(const T & t) -> decltype(std::make_unique<T>(t)) {
return std::make_unique<T>(t);
}
相关文章:
- 为什么使用SFINAE而不是函数重载
- 如何使用模板函数的函数签名进行SFINAE
- 数据成员SFINAE的C++17测试:gcc vs clang
- 使用在用于SFINAE的void_t中具有参数的方法
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 提供与TMP和SFINAE的通用接口
- "Inverse SFINAE"避免模棱两可的过载
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 如何在儿童类中使用SFINAE
- 使用 SFINAE 作为模板参数的编译时递归
- 使用 SFINAE 设计模板方法
- 与SFINAE支票交朋友
- C++许多 SFINAE 风格的过载
- 是否可以混合使用SFINAE和模板专业化?
- C++表达SFINAE和ostream操纵器
- SFINAE不能防止模棱两可的操作员过载吗?
- SFINAE是否取决于类型推断?
- MSVC 无法编译 SFINAE 检查
- SFINAE 检查模板参数运算符
- Is std::make_unique SFINAE-friendly?