2010-07-29 20 views
7

Argümanın türüne bağlı olarak koşullu olarak derlemek istediğim bir şablonum var. Sadece "Düz Eski Veri" (POD), yani tamsayılar, vb. Veya sınıflar/yapılar arasında ayrım yapmayı önemsiyorum. Windows üzerinde C++ VS2008 kullanıyorum.Destek Türü özelliklerini kullanarak Koşullu Derleme

template<T> 
class foo 
{ 
    void bar(T do_something){ 
    #if IS_POD<T> 
     do something for simple types 
    #else 
     do something for classes/structs 
    #endif 
}} 

Destek kitaplığına bakıyorum ve istediklerime sahip olduklarını görebiliyorum. Ancak, #if ifadesinin doğru sözdiziminin ne olacağını anlamıyorum.

Herhangi bir yardım için teşekkür ederiz.


Düzenleme --- yanıtları okuduktan sonra ben soru benim tanımında şey gözden bakın. Sınıf foo, class type T için doğru olan bar sürümünün yalnızca örnek olması gereken şablonlu bir sınıftır. Derleme zamanı çözülebilecek bir çözüm arıyordum. Umarım bu sorunu çözer.

cevap

7

: Boolean<true>/Boolean<false> hem IsPod<T>::result döner şey varsayarsak

. enable_if, aşırı yük çözünürlüğüne/şablon yükünü eklemek/kaldırmak için kullanılır. Nesneleri işleve iletmenin en iyi yöntemini seçmek için arama özelliklerini kullanmak isteyebilirsiniz. Kural olarak, nesneler referans ile geçirilirken, POD değer olarak geçirilir. call_traitsconst ve yapılandırmasız referansları arasında seçim yapalım. Aşağıdaki kod, const başvurusunu kullanır. sınıf şablonu t 'sabittir `örneği bir kez

#include <boost/type_traits.hpp> 
#include <boost/call_traits.hpp> 

template <typename T> 
class foo { 
public: 
    void bar(typename boost::call_traits<T>::param_type obj) { 
     do_something(obj, boost::is_pod<T>()); 
    } 
private: 
    void do_something(T obj, const boost::true_type&) 
    { 
     // do something for POD 
    } 
    void do_something(const T& obj, const boost::false_type&) 
    { 
     // do something for classes 
    } 
}; 
0

Burada önişlemci kullanmak mümkün değildir. Bunun yerine Boost Enable If library bir göz atın.

Özellikle, sizin durumunuzda o (test) gibi görünecektir: o C bilmediği beri ++, önişlemcisinden ile bu çözemezsiniz

void bar (typename enable_if <is_pod <T>, T>::type do_something) 
{ 
    // if is POD 
} 

void bar (typename disable_if <is_pod <T>, T>::type do_something) 
{ 
    // if not 
} 
+0

Bu, bir derleme hatası olacaktır ve bu noktada' çağrı iki tanımları göreceksiniz bar' çalıştığınızda ve derlemek başarısız olur onlardan biri. Bunun bir ikame hatası olmayacağı için SFINAE olmadığına dikkat edin. Bu, üyenin taklit edilmesinden önce sabittir (ya da bence, bu şeylerden asla emin değilim :)). –

3

. (Bu bir dilsiz metin değiştirme aracıdır.) Bunu yapmak için şablonlar kullanın. İhtiyacınız olan tüm tip özellikleri bağlı gönderme, çünkü Sen enable_if olmadan bunu yapabilir

template<T> 
class foo 
{ 
    void do_something(T obj, Boolean<true> /*is_pod*/) 
    { 
     // do something for simple types 
    } 
    void do_something(T obj, Boolean<false> /*is_pod*/) 
    { 
     // do something for classes/structs 
    } 

    void bar(T obj) 
    { 
     do_something(obj, IsPod<T>::result()); 
    } 
} 
İlgili konular