abraham_hilbert abraham_hilbert - 1 month ago 6
C++ Question

member function implementation depending on template parameter

I have the following problem:

template< typename T, size_t N, size_t... N_i >
class A
{
public:

// ...

// first implementation
template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M!=1, size_t >::type = 0 >
A<T, N_i...> operator[]( size_t i )
{
A< T, N_i... > res{ ... };

return res;
}

// second implementation
template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M==1, size_t >::type = 0 >
T operator[]( size_t i )
{
return ... ;
}
};


As you can see above, I try to implement a class
A
which expects as template arguments a type
T
(e.g.
int
or
float
) and
sizeof...(N_i)+1
-many
size_t
.

Dependent on the number of passed
size_t
(i.e.
sizeof...(N_i)+1
), I will use a different implementation for the member function
operator[](size_t)
with a different result type:


  • one implementation for the case
    sizeof...(N_i)+1 > 1
    with return type
    A < T, N_i... >

    (referred to as "first implementation" in the code)

  • and one for the case
    sizeof...(N_i)+1 == 1
    with return type
    T

    (referred to as "second implementation" in the code).



Unfortunately, I have no idea how this can be implemented -- the solution above does not work. Has anyone an idea?

Many thanks in advance.

Answer

A<T, N_i...> is invalid for empty N_i. As workaround, you may use indirection:

template <typename, std::size_t ...>
struct PopFrontA
{
    using type = void; // Dummy type for A<T, N>
};

template< typename T, std::size_t N, std::size_t... N_i > class A;

template <typename T, std::size_t N, std::size_t N2, std::size_t ... Ns>
struct PopFrontA<T, N, N2, Ns...>
{
    using type = A<T, N2, Ns...>;
};

template <typename T, std::size_t ... Ns>
using PopFrontA_t = typename PopFrontA<T, Ns...>::type;

And then

// first implementation
template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M!=1, size_t >::type = 0 >
PopFrontA_t<T, N, N_i...>
operator[]( size_t i )
{
  A< T, N_i... > res{ /*...*/ };

  return res;
}

Demo

Comments