I can't work this out.
I have a template class integer that has in its template parameter its value, and I want to add together n integers of this class. I can successfully get the int value from the class in the base case, but it fails otherwise.
template <int Value>
struct integer {};
template<int A, typename ...Rest>
auto constexpr add(integer<A>, Rest...) {
if constexpr (sizeof...(Rest) > 0)
return A add(Rest...);
else
return A;
}
int main(){
auto constexpr y = add(integer<1>{}); // base case
auto constexpr x = add(integer<1>{}, integer<2>{});
return 0;
}
My guess is that something is wrong with the parameters of the meta function
template<int A, typename ...Rest>
auto constexpr add(integer<A>, Rest...) {...}
but I just can't figure out what, in my mind it should always be able to deduce that its argument is an integer, and it shouldn't even instantiate if there are 0 arguments, yet that seems to be the case in the error logs:
(8, 17) : error C2144 : syntax error : 'integer<2>' should be preceded by ')'
(19) : message: see reference to function template instantiation 'auto add<1,integer<2>>(integer<1>,integer<2>)' being compiled
(8, 13) : error C2672 : 'add' : no matching overloaded function found
(7, 1) : error C2780 : 'auto add(integer<Value>,Rest...)' : expects 2 arguments - 0 provided
(7) : message: see declaration of 'add'
(8, 17) : error C2144 : syntax error : 'integer<2>' should be preceded by ';'
(7, 1) : error C2059 : syntax error : ')'
(19, 52) : error C3313 : 'x' : variable cannot have the type 'const void'
[
CodePudding user response:
add
is a function, not a metafunction, in the sense that you've designed it to take values (not types); in other words you call it like add(someValue)
(not like add<SomeType>
, fwiw).
So, the call to add(Rest...)
is syntactically wrong becaues you're passing a type instead of a value to add
; you should, instead, give that parameter a name, say rest
, and use that in the call:, as in add(rest...)
.