Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 339
Alexander Sergeyev Avatar asked Oct 27 '15 08:10

Alexander Sergeyev


1 Answers

template <typename A, bool sw>
struct B
{
    B() = default;

    B(const B& b) : B(b, std::integral_constant<bool, sw>{}) {}

private:
    B(const B& b, std::true_type)
    {
        std::cout << "true\n";
    }

    B(const B& b, std::false_type)
    {
        std::cout << "false\n";
    }
};

DEMO

like image 69
Piotr Skotnicki Avatar answered Nov 15 '22 17:11

Piotr Skotnicki