I am trying to translate run-time constant to compile-time constant in my C++11 program using switch
statement. I have enum SomeEnum {A, B, C};
, and depending on its value I want to call the template function f<A>()
, f<B>()
or f<C>()
. I have lots of template functions in my code that depend on SomeEnum
(as well as other template parameters), so I decided to make dedicated dispatch
function. Here is the code I am trying to compile:
#include <utility>
enum SomeEnum {
A, B, C
};
template<template<SomeEnum, typename...> class FUNCTOR, typename ...OTHERS, typename ...ARGS> inline auto dispatch (
SomeEnum const type,
ARGS&&... args
) -> decltype( FUNCTOR<A, OTHERS...>::function(std::forward<ARGS>(args)...) ) { //Problem here
switch(type) {
case A:
return FUNCTOR<A, OTHERS...>::function(std::forward<ARGS>(args)...);
case B:
return FUNCTOR<B, OTHERS...>::function(std::forward<ARGS>(args)...);
case C:
return FUNCTOR<C, OTHERS...>::function(std::forward<ARGS>(args)...);
default:
//Do not call any function if enum value is wrong, just return something:
return decltype( FUNCTOR<A, OTHERS...>::function(std::forward<ARGS>(args)...) )();
}
}
template<SomeEnum T> struct TemplateFunctor1 {
static inline int function(int) { return 0; }
};
template<SomeEnum T, class OTHER> struct TemplateFunctor2 {
static inline int function(int) { return 0; }
};
int main(void) {
dispatch<TemplateFunctor1>(B, 0); //Problem here!
dispatch<TemplateFunctor2, int>(B, 0);
return 0;
}
(I do not need to handle the case when function return type depends on template parameter)
I am getting an error while compiling the line dispatch<TemplateFunctor1>(B, 0);
, where is only one template parameter required by TemplateFunctor1
. The error messages are following:
error: no matching function for call to 'dispatch(SomeEnum, int)'
note: candidate: template<template<SomeEnum <anonymous>, class ...> class FUNCTOR, class ... OTHERS, class ... ARGS> decltype (FUNCTOR<(SomeEnum)0u, OTHERS ...>::function((forward<ARGS>)(dispatch::args)...)) dispatch(SomeEnum, ARGS&& ...)
note: template argument deduction/substitution failed
error: wrong number of template arguments (2, should be 1)
in this part of code: FUNCTOR<A, OTHERS...>
of trailing return type.
So I tried to change FUNCTOR<A, OTHERS...>
in trailing return type to FUNCTOR<A>
, then the line dispatch<TemplateFunctor2, int>(B, 0);
cannot be compiled. It says that I provided wrong number of template parameters (1, should be 2), which is quite an expected error.
What I do not understand here is why the same decltype()
construction works in default
switch branch, but does not work in the trailing return type?
I can fix my code by changing the standard to C++14 and by removing trailing return type completely, but then I will not understand what is going on here.
I also tried different compilers (ICC, GCC, Clang), and all of them giving similar error messages, so it cannot be a compiler error here.
Aucun commentaire:
Enregistrer un commentaire