C
Clark S. Cox III
I'm writing a class that, depending on a template parameter, has
constructors that take differing numbers of arguments. I initially
thought that I could use SFINAE (via boost::enable_if_c) to achieve my
ends, but I have hit a snag.
If I've messed up somewhere, or there's another way to get what I'm
after, I'd be greaful if someone could help me out.
Here is a condensed version of my code, showing the problem. Note that
I get the same problem regardless of whether FIRST_ATTEMPT is defined.
//--------------------------------
template<bool B, typename T>
struct Enabler
{
};
template<typename T>
struct Enabler<true, T>
{
typedef T type;
};
#if FIRST_ATTEMPT
template<unsigned N>
class Foo
{
public:
Foo() {}
explicit Foo(typename Enabler<N == 1, int>::type x) {}
Foo(typename Enabler<N == 2, int>::type x, int y) {}
Foo(typename Enabler<N == 3, int>::type x, int y, int z) {}
};
#else
template<unsigned N>
class Foo
{
struct private_type {};
public:
Foo() {}
explicit Foo(int x, typename Enabler<N == 1, private_type>::type =
private_type()) {}
Foo(int x, int y, typename Enabler<N == 2, private_type>::type =
private_type()) {}
Foo(int x, int y, int z, typename Enabler<N == 3, private_type>::type
= private_type()) {}
};
#endif
int main()
{
Foo<0> f0;
Foo<1> f1(1);
Foo<2> f2(1,2);
Foo<3> f3(1,2,3);
return 0;
}
//--------------------------------
The compiler tells me, several times that there is no type named ‘type’
in struct Enabler; which, I thought was the point of using SFINAE (i.e.
if there is no such type, then that overload is removed from the
resolution list).
constructors that take differing numbers of arguments. I initially
thought that I could use SFINAE (via boost::enable_if_c) to achieve my
ends, but I have hit a snag.
If I've messed up somewhere, or there's another way to get what I'm
after, I'd be greaful if someone could help me out.
Here is a condensed version of my code, showing the problem. Note that
I get the same problem regardless of whether FIRST_ATTEMPT is defined.
//--------------------------------
template<bool B, typename T>
struct Enabler
{
};
template<typename T>
struct Enabler<true, T>
{
typedef T type;
};
#if FIRST_ATTEMPT
template<unsigned N>
class Foo
{
public:
Foo() {}
explicit Foo(typename Enabler<N == 1, int>::type x) {}
Foo(typename Enabler<N == 2, int>::type x, int y) {}
Foo(typename Enabler<N == 3, int>::type x, int y, int z) {}
};
#else
template<unsigned N>
class Foo
{
struct private_type {};
public:
Foo() {}
explicit Foo(int x, typename Enabler<N == 1, private_type>::type =
private_type()) {}
Foo(int x, int y, typename Enabler<N == 2, private_type>::type =
private_type()) {}
Foo(int x, int y, int z, typename Enabler<N == 3, private_type>::type
= private_type()) {}
};
#endif
int main()
{
Foo<0> f0;
Foo<1> f1(1);
Foo<2> f2(1,2);
Foo<3> f3(1,2,3);
return 0;
}
//--------------------------------
The compiler tells me, several times that there is no type named ‘type’
in struct Enabler; which, I thought was the point of using SFINAE (i.e.
if there is no such type, then that overload is removed from the
resolution list).