2012-02-16 29 views
7

Eğer bu kadar açıksa cevabı bulamayacak kadar aptalım diye özür dilemeye başladım.C++: Bir işaretçiyi uzmanlaşmak için şablon nasıl önlenir?

işaretçisi parametreleri için belirli şablon uzmanlığı hakkında konuşurken onlarca sayfa gördük.

Ben işaretçi parametrelerini uzmanlaşmak için bir şablon önleme olsa da, muktedir istiyorum ama bunu nasıl anlamaya olamaz.

template< class T > 
void function(T arg) 
{ 
    //... 
} 

int main() 
{ 
    int i = 42; 

    function(i); // Ok 
    function(&i); // Die bastart with a compiler error! 
} 

Mümkün mü?

Teşekkürler.

+1

, sadece o 'şablon ' olmamalı static_assert – PlasmaHH

+1

kullanabilir? – Jacob

+0

@Jacob: şimdi düzeltildi. – MSalters

cevap

14

Sen (bu durumda sadece bir aşırı yük teknik olarak var) ihtisas ilan edemez ama bunu tanımlamak :)

template<typename T > 
void function(T arg) 
{ 
//... 
} 

template<typename T > 
void function(T* arg); //no definition 

int main() 
{ 
    int i = 42; 
    function(i); // Ok 
    function(&i); //ERROR 
} 
+0

Bu bir linker hatası mı yoksa derleme hatası mı? –

+4

@ daknøk: Bu bir derleyici hatası çünkü şablon. Şablonun tanımı aynı çeviri biriminde olmalıdır (kaynak dosya). Linker şablonlar hakkında hiçbir şey bilmiyor. Derleyici, şablon örneğinden sorumludur ve –

+0

+1 Hah tanımı olmadan bunu yapamaz, elbette, bu kadar kolay! Neden her zaman zor yoldan yapmak isterim? –

6

Kendimi şablon metaprogramming acemiyim ama

template<typename T> 
void function(typename std::enable_if<!std::is_pointer<T>::value,T>::type arg) 
{ 
    //... 
} 
düşünüyorum

çalışmalıdır, çünkü bu işlev yalnızca işaretçi olmayan parametreler için mevcut olmalıdır. Elbette bu, C++ 11 veya en azından TR1 veya boost'un tip özellikleri tesislerini gerektirir.

+0

+1 Bir alternatif sınamaktaydım (biraz daha fazla kullanıyorum): Şablon typename enable_if :: value> :: type function (T arg) ', ancak sizinki de çalışmalısınız. (Ve her iki tetikleyici * derleyici * hatalar, bağlayıcı hataları yerine) –

7

C++ 11 yılında böyle bir yolla static_assert kullanabilirsiniz:

template<class T> 
void func(T arg) { 
    static_assert(!std::is_pointer<T>::value, 
       "The argument to func must not be a pointer."); 
    // Do something after the static_assert. 
    // Now you are sure that T isn't a pointer. 
} 

bir örnek

here on Ideone bulunabilir. Biri bir pointer ile işlevini çağırmak çalıştığında daha yararlı hata iletileri verecektir çünkü

bu tavsiye (bağlayıcı hataları bu durumda çok kafa karıştırıcı olabilir). Ayrıca, bağlantı oluşmadan önce bağlayıcı hataları görünmeyecektir. Eğer C++ 11 erişiminiz olduğunda

İlgili konular