为什么失败的enable_if导致编译时错误?

时间:2017-10-27 08:37:11

标签: c++11 templates

我想有条件地禁用某些模板类的复制构造函数。换句话说,如果基类型不是可复制构造的,我想要禁用复制构造函数。为了解决这个问题(在教育目的)我决定写下面的程序。 (这里是ideone https://ideone.com/QY0NHJ的链接)以下是我的计划的来源:

#include <algorithm>
#include <type_traits>

using namespace std;

template <typename Data>
class Container
{
public: 
    typedef Container<Data> self_type;

    Container(): 
        m_data()
    {
    }

    Container(const typename 
std::enable_if<std::is_copy_constructible<Data>::value, 
            self_type>::type& other_data) : 
        m_data(other_data.m_data)
    {
    }

    Container(self_type&& other)
    {
        std::swap(m_data, other.m_data);
    }

private:
    Data m_data;
};

class SomeData
{
public:
    SomeData(){}
    SomeData(const SomeData&) = delete;
};

int main() 
{
    Container<SomeData> container;
    return 0;
}

但是来自编译器的消息让我很困惑:

  

prog.cpp:在'class Container'的实例化中:   prog.cpp:41:22:从这里要求   prog.cpp:17:2:错误:'struct std :: enable_if&gt;'中没有名为'type'的类型     容器(const typename std :: enable_if :: value

根据我的理解,它应该导致SFINAE并且不应该从编译器中产生任何东西。我哪里错了?

1 个答案:

答案 0 :(得分:2)

  

据我了解,它应该导致SFINAE

SFINAE意味着“替换失败不是错误”。你需要替换才能使SFINAE出局。在这种情况下,只需将默认模板参数添加到复制构造函数中即可:

template <typename D = Data>
Container(const typename std::enable_if<std::is_copy_constructible<D>::value, 
        self_type>::type& other_data) : 
    m_data(other_data.m_data)
{
}

live example on wandbox