I have the following (partial) code in a class where I try to evaluate a value against a list of values via metaprogramming in C++11.
bool eval(GLenum value)
{
return false;
};
template<GLenum One, GLenum... Others>
bool eval(GLenum value)
{
if( value == One )
return true;
// Try out the rest
return eval<Others...>(value);
};
gcc complains:
../emul/GLPart.h: In member function ‘bool
GLPart::eval(GLenum) [with unsigned int One = 519u,
unsigned int …Others = {}, unsigned int …ValidEnums = {512u, 513u,
514u, 515u, 516u, 517u, 518u, 519u}, GLenum = unsigned int]’:
../emul/GLPart.h:26:31: instantiated from ‘bool
GLPart::eval(GLenum) [with unsigned int One = 518u,
unsigned int …Others = {519u}, unsigned int …ValidEnums = {512u,
513u, 514u, 515u, 516u, 517u, 518u, 519u}, GLenum = unsigned int]’
../emul/GLPart.h:26:31: instantiated from ‘bool
GLPart::eval(GLenum) [with unsigned int One = 517u,
unsigned int …Others = {518u, 519u}, unsigned int …ValidEnums =
{512u, 513u, 514u, 515u, 516u, 517u, 518u, 519u}, GLenum = unsigned
int]’ ../emul/GLPart.h:26:31: instantiated from ‘bool
GLPart::eval(GLenum) [with unsigned int One = 516u,
unsigned int …Others = {517u, 518u, 519u}, unsigned int
…ValidEnums = {512u, 513u, 514u, 515u, 516u, 517u, 518u, 519u},
GLenum = unsigned int]’ ../emul/GLPart.h:26:31: instantiated from
‘bool GLPart::eval(GLenum) [with unsigned int One = 515u,
unsigned int …Others = {516u, 517u, 518u, 519u}, unsigned int
…ValidEnums = {512u, 513u, 514u, 515u, 516u, 517u, 518u, 519u},
GLenum = unsigned int]’ ../emul/GLPart.h:26:31: instantiated from
‘bool GLPart::eval(GLenum) [with unsigned int One = 514u,
unsigned int …Others = {515u, 516u, 517u, 518u, 519u}, unsigned int
…ValidEnums = {512u, 513u, 514u, 515u, 516u, 517u, 518u, 519u},
GLenum = unsigned int]’ ../emul/GLPart.h:26:31: instantiated from
‘bool GLPart::eval(GLenum) [with unsigned int One = 513u,
unsigned int …Others = {514u, 515u, 516u, 517u, 518u, 519u},
unsigned int …ValidEnums = {512u, 513u, 514u, 515u, 516u, 517u,
518u, 519u}, GLenum = unsigned int]’ ../emul/GLPart.h:26:31:
instantiated from ‘bool GLPart::eval(GLenum) [with
unsigned int One = 512u, unsigned int …Others = {513u, 514u, 515u,
516u, 517u, 518u, 519u}, unsigned int …ValidEnums = {512u, 513u,
514u, 515u, 516u, 517u, 518u, 519u}, GLenum = unsigned int]’
../emul/GLPart.h:31:43: instantiated from ‘bool
GLPart::Evaluate(GLenum) [with unsigned int …ValidEnums
= {512u, 513u, 514u, 515u, 516u, 517u, 518u, 519u}, GLenum = unsigned
int]’ alpha.cpp:8:7: instantiated from here ../emul/GLPart.h:26:31:
error: no matching function for call to ‘GLPart<512u, 513u, 514u,
515u, 516u, 517u, 518u, 519u>::eval(GLenum&)’
So it seems like it chokes on the last recursion when One has a value and Others don’t. In this case the template parameters should then be empty. Do I need to declare the ordinary eval in another way? Haven’t coded C++ in a while so it may be trivial but I just don’t get it 😉
When trying to add template<> to the first eval it chokes:
../emul/GLPart.h:14:11: error: explicit specialization in
non-namespace scope ‘class GLPart’ ../emul/GLPart.h:21:7:
error: too many template-parameter-lists ../emul/GLPart.h: In member
function ‘bool GLPart::Evaluate(GLenum)’:
../emul/GLPart.h:32:23: error: parameter packs not expanded with
‘…’: ../emul/GLPart.h:32:23: note: ‘ValidEnums’
../emul/GLPart.h:32:33: error: expected ‘,’ or ‘;’ before ‘…’ token
Solution:
template<GLenum One>
bool eval(GLenum value)
{
return value == One;
};
template<GLenum One, GLenum Two, GLenum... Others>
bool eval(GLenum value)
{
if( eval<One>(value) )
return true;
// Try out the rest
return eval<Two, Others...>(value);
};
Since this tends to produce lots of ambiguity errors, the variation that seems to work unambigously looks like this:
The first overload takes exactly one argument, the second at least two. Taking zero arguments probably doesn’t make sense anyway.