2016-03-11 30 views
19

Derleme zamanında türün adını kullanmak istiyorum. Sadece const char* değil ... diğer bazı, constexpr yol var constexpr typeid(T).name() olduğunu, ne yazık kiC++ tipi adlarını constexpr biçiminde alabilir miyim?

template <typename T> 
constexpr auto type_name_length = my_strlen(typeid(T).name()); 

Ama:

constexpr size_t my_strlen(const char* s) 
{ 
     const char* cp = s; 
     while(*cp != '\0') { cp++; }; 
     return cp - s; 
} 

ve şimdi istiyorum: Mesela ben yazdım varsayalım Bir türün adını almak için?

+0

'type_name_length 'ile derleme zamanında ihtiyacınız olan şey nedir? Derleyiciler sadece strlen() 'i değerlendirmek ve eğer mümkün olursa size sabit vermek konusunda oldukça iyidir. – Barry

+0

@Barry: Burada sadece bir MCVE istedim, bu yüzden sentetik bir kullanım yaptım. – einpoklum

+0

@einpoklum Bu iyi; ama (bu sadece bir MCVE, ben gerçekten X için çalışıyorum) soruda olduğunu söyleyerek bir yorum ekleyerek de iyidir. – Yakk

cevap

50

Eh, ilgilenir misin, çeşit, ama muhtemelen oldukça taşınabilir:

struct string_view 
{ 
    char const* data; 
    std::size_t size; 
}; 

inline std::ostream& operator<<(std::ostream& o, string_view const& s) 
{ 
    return o.write(s.data, s.size); 
} 

template<class T> 
constexpr string_view get_name() 
{ 
    char const* p = __PRETTY_FUNCTION__; 
    while (*p++ != '='); 
    for (; *p == ' '; ++p); 
    char const* p2 = p; 
    int count = 1; 
    for (;;++p2) 
    { 
     switch (*p2) 
     { 
     case '[': 
      ++count; 
      break; 
     case ']': 
      --count; 
      if (!count) 
       return {p, std::size_t(p2 - p)}; 
     } 
    } 
    return {}; 
} 

Ve Tanımlayabileceğiniz senin arzu type_name_length olarak:

template <typename T> 
constexpr auto type_name_length = get_name<T>().size; 

DEMO (çınlama & g ++ için çalışır)

+2

Benzer bir şey, '__FUNCSIG__' ile MSVC üzerinde uygulanabilir. – melak47

+2

Sadece C++ 14 veya üstü için çalışıyor, tabi ki. – einpoklum

+0

[bu site] 'yi (http://rextester.com/l/cpp_online_compiler_visual) buldum ve __FUNCSIG__' testini yaptım. GCC'nin hibrit çıkışının tersine, işlev açıkça açıklanmış gibi, tamamen değiştirilmiş/bağlı türler yayar. Örneğin: void __cdecl foo (const double &) ', bana bir bakışta daha az yardımcı olur. (GCC, bağımlı ve serbest türler arasında belki de garip bir ayrım yapar, ya da ikameler gerçekleştirilirken belki de hesaplanmış türlere karşı çıkarımlar yapar.) Bence, düşüncenin oldukça yetersiz ve yetersiz desteklendiğini düşünüyorum. Ufukta şu ana kadarki Kavramlar ile ... –

İlgili konular