7

Могу ли я использовать вариативные шаблоны без использования параметров шаблона в качестве параметров функции?Шаблоны Variadic без функциональных параметров

Когда я использую их, он компилирует:

#include <iostream> 
using namespace std; 

template<class First> 
void print(First first) 
{ 
    cout << 1 << endl; 
} 

template<class First, class ... Rest> 
void print(First first, Rest ...rest) 
{ 
    cout << 1 << endl; 
    print<Rest...>(rest...); 
} 

int main() 
{ 
    print<int,int,int>(1,2,3); 
} 

Но когда я не использую их, он не компилируется и жалуется на двусмысленности:

#include <iostream> 
using namespace std; 

template<class First> 
void print() 
{ 
    cout << 1 << endl; 
} 

template<class First, class ... Rest> 
void print() 
{ 
    cout << 1 << endl; 
    print<Rest...>(); 
} 

int main() 
{ 
    print<int,int,int>(); 
} 

К сожалению, классы I хотите дать, поскольку параметры шаблона не являются реальными (у них есть статические функции, которые вызываются внутри функции шаблона). Есть ли способ сделать это?

+1

Если вам нужно * невычисленное * выражение данного типа, вы можете использовать 'станд :: declval ()'. Работает для любого 'T', независимо от его конструктивности. –

+4

Что касается того, почему версия без аргументов не работает: без аргументов обе перегрузки 'print ' и 'print ' одинаково хороши, в то время как с аргументами 'print (3)' лучше совпадение, чем 'print (3, {}) '(где' {} 'означает« ничего »). Не использование перегрузок, как предлагает CatPusPus, является стандартным методом; и поскольку вы не выносите свои аргументы, это самое простое решение. –

+0

Я собирался опубликовать ответ, но н.м. уже отправил его. – bames53

ответ

20
template<class First> // 1 template parameter 
void print() 
{ 
    cout << 1 << endl; 
} 

#if 0 
template<class First, class ... Rest> // >=1 template parameters -- ambiguity! 
void print() 
{ 
    cout << 1 << endl; 
    print<Rest...>(); 
} 
#endif 

template<class First, class Second, class ... Rest> // >=2 template parameters 
void print() 
{ 
    cout << 1 << endl; 
    print<Second, Rest...>(); 
} 
+1

Вы можете избавиться от дублирования кода, вызывая 'print ()' от самой нижней версии, вместо того, чтобы повторять строку 'cout'. Я думаю. –

8

Сделайте это типом.

template <typename... Ts> 
struct print_impl; 

template <typename T> 
struct print_impl<T> { 
    static void run() { 
     std::cout << 1 << "\n"; 
    } 
}; 

template <typename T, typename... Ts> 
struct print_impl<T, Ts...> { 
    static void run() { 
     std::cout << 1 << "\n"; 
     print_impl<Ts...>::run(); 
    } 
}; 

template <typename... Ts> 
void print() { 
    print_impl<Ts...>::run(); 
} 

int main() { 
    print<int, int, int>(); 
    return 0; 
} 
+0

Я считаю, что сложность здесь не заслуживает. Решение n.m. является гораздо более простым. – bames53

 Смежные вопросы

  • Нет связанных вопросов^_^