mardi 27 octobre 2015

selecting appropriate copy-constructor based on template parameters

I want to select implementation of a member function (copy constructor) based on a template argument value. I suppose there are two approaches: SFINAE and template partial specialization.

The last one supposedly looks like this:

#include <iostream>

template<typename A, bool sw>
struct B
{
    B() {}
    B(const B &b);
};

template<typename A>
B<A, false>::B(const B<A, false> &b)
{
    std::cout << "false\n";
}

template<typename A>
B<A, true>::B(const B<A, true> &b)
{
    std::cout << "true\n";
}

int main()
{
}

It doesn't compile: nested name specifier 'B<A, false>::' for declaration does not refer into a class, class template or class template partial specialization.

SFINAE approach fails too:

#include <type_traits>
#include <iostream>

template<typename A, bool sw>
struct B
{
    B() {}

    template<typename U = typename std::enable_if<sw, B>::type>
    B(const U &b)
    {
        std::cout << "true\n";
    }

    template<typename U = typename std::enable_if<!sw, B>::type>
    B(const U &b)
    {
        std::cout << "false\n";
    }
};

int main()
{
    {
        B<int, true> b;
        auto bc = b; // cout << true
    }
    {
        B<int, false> b;
        auto bc = b; // cout << false
    }
}

The compilation error here is constructor cannot be redeclared and no type named 'type' in 'std::enable_if<false, B<int, false> >'; 'enable_if' cannot be used to disable this declaration.

Is there any way to fix the problems or otherwise select appropriate copy-constructor based on template parameters?

Aucun commentaire:

Enregistrer un commentaire