2013-03-24 9 views
13

std::is_integral<>::value doğruysa, int64_t döndürmeye çalışıyorum.Bir uygulamayı seçmek için std :: is_integral <> öğesini nasıl kullanırım?

Aksi takdirde, nesne üzerinde to_int64t() numaralı telefonu aramak istiyorum.

İşlevlerim şablonlarının kısmi özelleştirilmesine izin verilmediğinden aşağıdaki denemem başarısız oluyor.

KOD

#include <type_traits> 
#include <cstdint> 

template<class T,bool is_integral_type> 
int64_t to_int64t(const T& t) 
{ 
     return t; 
} 

template<class T> 
int64_t to_int64t<T,std::is_integral<T>::value>(const T& t) 
{ 
     return t; 
} 

template<class T> 
int64_t to_int64t<T,!std::is_integral<T>::value>(const T& t) 
{ 
     return t.to_int64t(); 
} 

int main() 
{ 
     int64_t i = 64; 
     auto x = to_int64t(i); 
} 
+0

olası yinelenen: Ben bu kullanım şeklini bu tekniği kullanmak ister ama ilgili tasarım durumlarda kullanışlı gelebilir çünkü o gösteriyorum - bir detail ad alanında) kısmen özelleşmiş olabilir ve küresel bir iletici sağlamak http://stackoverflow.com/questions/12073689/c11-template-function-specialization-for-integer-types – legends2k

cevap

28

Fonksiyon şablonları genel olarak kısmen özelleşmiş ve olamaz, işlev şablon uzmanlık kullanmak iyi bir fikir değildir.

#include <type_traits> 
#include <cstdint> 

template<class T> 
int64_t to_int64t(const T& t, std::true_type) 
{ 
    return t; 
} 

template<class T> 
int64_t to_int64t(const T& t, std::false_type) 
{ 
    return t.to_int64t(); 
} 

template<class T> 
int64_t to_int64t(const T& t) 
{ 
    return to_int64t(t, std::is_integral<T>()); 
} 

int main() 
{ 
    int64_t i = 64; 
    auto x = to_int64t(i); 
} 
: İstediğinizi elde etmek

bir yolu temelde ekstra kukla argüman değerine dayalı olarak doğru aşırı seçen bir iletici işlevini temin edilmesinden ibaret sevk etiketi adı verilen bir teknik kullanmaktır

Başka bir olasılık, std::enable_if tabanlı klasik SFINAE tekniğini kullanmaktır. Bu durum (C++ 11, işlev şablonlarında varsayılan şablon argümanları izin verilir çünkü fark) gibi görünebilir nasıl:

#include <type_traits> 
#include <cstdint> 

template<class T, typename std::enable_if< 
    std::is_integral<T>::value>::type* = nullptr> 
int64_t to_int64t(const T& t) 
{ 
    return t; 
} 

template<class T, typename std::enable_if< 
    !std::is_integral<T>::value>::type* = nullptr> 
int64_t to_int64t(const T& t) 
{ 
    return t.to_int64t(); 
} 

int main() 
{ 
    int64_t i = 64; 
    auto x = to_int64t(i); 
} 

Yine bir başka ihtimal, yardımcı sınıf şablonları tanımlamaktır daha ayrıntılı rağmen (ki

#include <type_traits> 
#include <cstdint> 

namespace detail 
{ 
    template<class T, bool = std::is_integral<T>::value> 
    struct helper { }; 

    template<class T> 
    struct helper<T, true> 
    { 
     static int64_t to_int64t(const T& t) 
     { 
      return t; 
     } 
    }; 

    template<class T> 
    struct helper<T, false> 
    { 
     static int64_t to_int64t(const T& t) 
     { 
      return t.to_int64t(); 
     } 
    }; 
} 

template<class T> 
int64_t to_int64t(const T& t) 
{ 
    return detail::helper<T>::to_int64t(t); 
} 

int main() 
{ 
    int64_t i = 64; 
    auto x = to_int64t(i); 
} 
+0

+1 t y - Bunu – kfmfe04

+0

Oh deneyeceğim, bu güzel. :) – 0x499602D2

+0

@PeteBecker: Düzenleme için teşekkürler :) –

5

sadece std::enable_if kullanabilirsiniz:

template<class T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> 
int64_t to_int64t(const T& t) 
{ 
     return t; 
} 

template<class T, typename std::enable_if<!std::is_integral<T>::value, int>::type = 0> 
int64_t to_int64t(const T& t) 
{ 
     return t.to_int64t(); 
} 
İlgili konular