0
votes

I want to disable copy constructor of some template class conditionally. In other words, I want disable copy constructor, if base type is not copy constructible. To solve such problem (in educational purposes) I decided to write following program. (Here is link to ideone https://ideone.com/QY0NHJ) Below is source of my program:

#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;
}

But message from compiler really confuses me:

prog.cpp: In instantiation of ‘class Container’: prog.cpp:41:22: required from here prog.cpp:17:2: error: no type named ‘type’ in ‘struct std::enable_if >’ Container(const typename std::enable_if::value

As I understand it should lead to SFINAE and nothing should be arised from compiler. Where am I wrong?

1

1 Answers

2
votes

As I understand it should lead to SFINAE

SFINAE means "substitution failure is not an error". You need substitution to occur in order to SFINAE out something. In this case, it is sufficient to add a default template parameter to your copy constructor:

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