ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – std :: make_unique SFINAE友好吗?

2019-08-24 05:05:50  阅读:184  来源: 互联网

标签:c c11 sfinae unique-ptr


我正在做一些模板元编程,我想实现一个通用的克隆函数,它根据SFINAE表达式的有效性选择克隆方法(替换失败不是错误).

this reference website它说

The function

make_unique<T>( std::forward<Args>(args)... )

is equivalent to:

06001

这是否意味着以下代码

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而参与重载决策.

这是一个小例子,无法在启用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>(新T(std :: forward< Args>(args)…)),它不能保证只有在使用Args …构造T时才能存在make_unique函数,所以它不是SFINAE友好的(按照标准),所以你不能依赖它.

标准中唯一提到make_unique的部分:

§20.8.1.4 [unique.ptr.create]:

06001

  1. Remarks: This function shall not participate in overload resolution unless T is not an array.
  2. Returns: unique_ptr<T>(new T(std::forward<Args>(args)...)).

在您的情况下,您可能希望使用带有std :: unique_ptr< T>(new T(…))的版本或使用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);
}

标签:c,c11,sfinae,unique-ptr
来源: https://codeday.me/bug/20190824/1704957.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有