【问题标题】:Why does failed enable_if lead to compile time error?为什么失败的 enable_if 会导致编译时错误?
【发布时间】:2018-04-08 19:27:41
【问题描述】:

我想有条件地禁用某些模板类的复制构造函数。换句话说,如果基类型不可复制构造,我想禁用复制构造函数。为了解决这样的问题(出于教育目的),我决定编写以下程序。 (这里是ideonehttps://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:在“类容器”的实例化中: prog.cpp:41:22: 从这里需要 prog.cpp:17:2:错误:“struct std::enable_if >”中没有名为“type”的类型 Container(const typename std::enable_if::value

据我了解,它应该导致 SFINAE,编译器不应该产生任何东西。我哪里错了?

【问题讨论】:

    标签: c++11 templates


    【解决方案1】:

    据我了解,它应该导致 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

    【讨论】:

    • 谢谢,此代码有效。但是为什么要添加模板参数D呢?我认为使用模板参数Data就足够了
    • @LmTinyToon: Data 在类被实例化时被替换。 D 在实例化复制 ctor 时被替换。
    猜你喜欢
    • 1970-01-01
    • 2012-12-07
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    相关资源
    最近更新 更多