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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With