#c #c 11
#c #c 11
Вопрос:
Я использую переменную шаблонную функцию, где параметры функции не являются шаблонными типами.
Я получил ошибку компиляции:
Ошибка C2668 ‘_TailHelper’: неоднозначный вызов перегруженной функции
Вот это фрагмент кода.
template <typename HEAD>
void _TailHelper(int) {
std::cout << typeid(HEAD).name() << std::endl;
}
template <typename HEAD, typename ... TAILS>
void _TailHelper(int x) {
_TailHelper<HEAD>(x);
_TailHelper<TAILS...>(x);
}
int main(){
_TailHelper<int,double>(2);
}
Комментарии:
1. Вы забыли объяснить, как вы компилируете, и полностью процитировать ошибку компилятора.
2. имена, начинающиеся с
_
, за которыми следует заглавная буква, зарезервированы.3. что должно
_TailHelper<HEAD>(x);
вызывать? Ваш компилятор не знает, и мы также не можем4. Конечно, это неоднозначно,
_TailHelper<int>
соответствует обоим шаблонам,TAILS
может быть пустым.5. Кроме того, пожалуйста, не
SHOUT
делайте ничего, кромеMACRO_NAMES
, и не используйте макросы. Если вы хотите соглашение, которое выделяет аргументы шаблона из других имен, попробуйте, напримерT_Head
, иT_Tails
или что-то еще, но нетALL_CAPS
.
Ответ №1:
Обе перегрузки совпадают с одним аргументом шаблона, поэтому вы должны отключить его. Например, так:
#include <iostream>
#include <typeinfo>
template <typename T>
void TailHelper(int) {
std::cout << typeid(T).name() << std::endl;
}
template <typename HEAD, typename ... TAILS>
typename std::enable_if<(sizeof...(TAILS) != 0)>::type
TailHelper(int x) {
TailHelper<HEAD>(x);
TailHelper<TAILS...>(x);
}
int main() {
TailHelper<int,double>(2);
}
Ответ №2:
Неоднозначный вызов исходит из этой строки:
_TailHelper<HEAD>(x);
этот вызов соответствует обеим функциям — первой и второй функции, второй параметр которой может ссылаться на ноль или более параметров шаблона.
Ответ №3:
В качестве альтернативы рекурсии вы можете «перебирать» свои переменные:
В C 17:
template <typename... Ts>
void PrintTypes() {
((std::cout << typeid(Ts).name() << std::endl), ...);
}
В предыдущей версии это было менее элегантно, и вы могли бы использовать какой-нибудь трюк, как:
template <typename... Ts>
void PrintTypes() {
const int dummy[] = {0, ((std::cout << typeid(Ts).name() << std::endl), 0)...};
static_cast<void>(dummy); // Avoid warning for unused variable
}