I recently started trying out various template tricks. In this case I tried to implement a class holding a sequence of numbers supplied by a variadic template utilizing a parameter pack.
However, I run into some problems that do not occur on the compiler I use (Intel C++ 14), but on others like CLang or GCC. I am therefore quite confused about which compiler is "more on point" in its interpretation of the standard.
Here is my code:
#include <iostream>
using namespace std;
template< size_t... Sequence >
class CSequence
{
public:
CSequence()
{
this->generate< Sequence... >();
this->out();
}
private:
// Recursion end
template< size_t N >
void generate(size_t sz)
{
// Create array
this->m_Array = new size_t[sz+1];
this->m_Len = sz+1;
this->m_Array[sz] = N;
}
// Recursion segment
template< size_t N, size_t... Ns >
void generate(size_t sz)
{
generate<Ns...>(sz+1);
this->m_Array[sz] = N;
}
// Recursion start
template< size_t... Ns >
void generate()
{
generate<Ns...>(0);
}
void out()
{
for(int i = 0; i < this->m_Len; i++)
{
std::cout << this->m_Array[i] << " ";
}
std::cout << std::endl;
}
private:
size_t* m_Array;
size_t m_Len;
};
int main()
{
CSequence< 1, 2, 3, 4, 5, 6, 7, 8 > a;
std::getchar();
}
This compiles fine on my end using Intel C++ 14 and produces the result I would expect:
1 2 3 4 5 6 7 8
But on the newest versions of both CLang and GCC it fails to compile:
Now, I can actually understand the reason for the failure: As parameter packs can contain zero elements, the exemplary call
generate< 8 >( size_t );
may be resolved both as
generate < N = 8, Ns = <> > ( size_t )
and as
generate < N = 8 > ( size_t )
thus resulting in an unresolvable ambiguity. But the fact that it compiles on my end and actually gives the expected result makes me wonder:
- Which compiler is "right"? Obviously Intel C++ makes some additional decisions compared to CLang or GCC. Is this "illegal" concerning the standard? Or are the GCC/CLang simply lacking?
- Are there any ways to circumvent this behaviour?
Note that this piece of code is to be considered as some kind of experiment, so I'm happy with both alternative strategies as well as fixes for this particular piece of code.
Aucun commentaire:
Enregistrer un commentaire