How is it supposed to know what x
is from outside the function? (It can't look into the body, because in which body of which function it looks depends on what value x
gets!). Also you cannot write that ?:
because both your branches yield totally unrelated types that can't possibly get to a common type. But that operator requires to have a common type for both branches that it evaluates to.
And then the other problem you have that size
is not a compile time constant is already elaborated by another post.
I think this should work:
template<int y, int z>
someclass<sizeof (char[+(y >= z)]) * y> anotherfunc(someclass<y> A, someclass<z> B){
return A;
}
template<int y, int z>
someclass<sizeof (char[+(y < z)]) * z> anotherfunc(someclass<y> A, someclass<z> B){
return B;
}
Now when calling it, y
and z
are deduced by the parameters, and then the parameters are substituted into the return type. The sizeof(char[1 or 0])
will test whether y
or z
is greater. In the respective template that evaluates this to sizeof(char[1])
(which yields 1) we will multiply by the value that is greater (or equal). If the respective template yields sizeof(char[0])
this is a deduction failure (an array can't be of zero size!) and the template won't get selected by overload resolution (known as SFINAE).
The unary +
yields 1
or 0
as int instead of true
or false
, which could cause compiler warnings for some compilers.
There is also the "clean" way with enable_if
. It's not doing hideous sizeof
tricks, but rather using the general established enable_if pattern. Boost has an implementation of it
template<int y, int z>
typename boost::enable_if_c<(y >= z), someclass<y> >::type
anotherfunc(someclass<y> A, someclass<z> B){
return A;
}
template<int y, int z>
typename boost::enable_if_c<(y < z), someclass<z> >::type
anotherfunc(someclass<y> A, someclass<z> B){
return B;
}
This may at first sight look more noisy, but should be easier to understand and faster to follow to folks that are already used to enable_if
(the _c
variant of boost's implementation accepts plain booleans, as above).