2012-04-23 29 views
7

Şablon parametrelerini işlev parametreleri olarak kullanmadan variadic şablonları kullanabilir miyim?İşlevsel parametreler olmadan Variadic şablonları

#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); 
} 

Ama onları kullanmadığınızda, bu derleme değil ve bir belirsizlik hakkında şikayet:

Bunları kullandığınızda, derler

#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>(); 
} 

Maalesef sınıfları I şablon parametrelerinin örneklenemez olması (şablon işlevinin içinde çağrılan statik işlevler vardır) olarak vermek istiyorum. Bunu yapmanın bir yolu var mı?

+1

'std :: declval ()'. Yapılandırılabilir olsun ya da olmasın, herhangi bir “T” için çalışır. –

+4

No argüman versiyonunun neden çalışmadığı: Argümanlar olmadan, her iki aşırı yüklenme baskı 've' print 'eşittir, argümanlar ise baskı (3)' baskı 'dan daha iyi bir eştir. (3, {}) '(burada {}," hiçbir şey "anlamına gelir). CatPusPus'un öne sürdüğü gibi aşırı yüklenmeler kullanılmamak, standart yöntemdir; ve siz argümanlarınızı çıkarmıyorsunuz, çünkü bu en basit çözümdür. –

+0

Bir cevap gönderecektim ama n.m. zaten gönderdi. – bames53

cevap

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

"cout" satırını yinelemek yerine, en alt sürümden baskıyı () 'çağırarak kod çoğaltmasından kurtulabilirsiniz. Bence. –

8

Bunu bir tür yapın. Belirli bir türde bir * unevaluated * ifadesini gerekiyorsa, kullanabilirsiniz

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

Buradaki karmaşıklığın haklı olmadığını düşünüyorum. n.m. çözümü çok daha basit. – bames53

İlgili konular