Я пытаюсь преобразовать константу времени выполнения в константу времени компиляции в моей программе на C ++ 11, используя оператор switch
. У меня enum SomeEnum {A, B, C};
, и в зависимости от его значения я хочу вызвать функцию-шаблон f<A>()
, f<B>()
или f<C>()
. В моем коде много шаблонных функций, которые зависят от SomeEnum
(а также от других параметров шаблона), поэтому я решил сделать специальную функцию dispatch
. Вот код, который я пытаюсь скомпилировать:
#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;
}
(мне не нужно обрабатывать случай, когда тип возвращаемого значения функции зависит от параметра шаблона)
Я получаю сообщение об ошибке при компиляции строка dispatch<TemplateFunctor1>(B, 0);
, где только один параметр шаблона, требуемый TemplateFunctor1
. Сообщения об ошибках следующие:
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)
в этой части кода: FUNCTOR<A, OTHERS...>
конечного возвращаемого типа.
Итак, я попытался изменить FUNCTOR<A, OTHERS...>
в конечном возвращаемом типе на FUNCTOR<A>
, тогда строка dispatch<TemplateFunctor2, int>(B, 0);
не может быть скомпилирована. В нем говорится, что я указал неправильное количество параметров шаблона (1, должно быть 2), что является вполне ожидаемой ошибкой.
Я не понимаю, почему та же конструкция decltype()
работает в default
переключить ветвь, но не работает в завершающем возвращаемом типе?
Я могу исправить свой код, изменив стандарт на C ++ 14 и полностью удалив конечный возвращаемый тип, но тогда я не пойму, что происходит здесь.
Я также пробовал разные компиляторы (I CC, G CC, Clang), и все они выдают похожие сообщения об ошибках, поэтому здесь не может быть ошибки компилятора.