3

Let N be a template parameter of type std::size_t. I would like to be able to call the constructor for my class in two ways:

A a(x1, x2, x3, ..., xN)

and

A a(x1, x2, x3, ..., xN, xN1)

where the xi variables are all of the same type. My first thought was to do:

template <std::size_t N>
struct A
{
     template <typename ...Args, typename = typename std::enable_if<N == sizeof...(Args), void>::type>
     A(Args ...args) {
         f(args...); // where f is some function
     }

     template <typename ...Args, typename = typename std::enable_if<N+1 == sizeof...(Args), void>::type>
     A(Args ...args) {
         // run f on the first N arguments
         // run g on the last argument (selection is done using templates, I just did not want to write the code)
     }
};

This technique is explained at: Variadic templates with exactly n parameters. Of course, the problem with this is that you cannot overload the constructor this way.

Any ideas?

Community
  • 1
  • 1

1 Answers1

4

Just SFINAE it differently:

template <std::size_t N>
struct A
{
     template <typename ...Args, 
               typename std::enable_if<N == sizeof...(Args), int>::type = 0>
     A(Args ...args) {
     }

     template <typename ...Args, 
               typename std::enable_if<N+1 == sizeof...(Args), int>::type = 0>
     A(Args ...args) {
     }
};

Demo.

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • Could you explain the difference? – David G Oct 11 '14 at 15:38
  • @0x499602D2 The one in the OP redefines the same function template (with a different default argument). Making the `enable_if` part of the signature makes these two distinct function templates. – T.C. Oct 11 '14 at 15:42
  • So should the former ever be used for SFINAE? – David G Oct 11 '14 at 15:51
  • Both are fine in general. The first just can't be used if the overloads would otherwise have the exact same signature. – T.C. Oct 11 '14 at 15:55