2016-04-05 4 views
0

J'essaye d'implémenter le code de taille pour le format de cbor avec "SFINAE", faute d'un meilleur mot. Mais cela ne fonctionne pas, comme size_code<3>, par exemple, évalue à 0x1b. Qu'est-ce qui ne va pas?modèle de variable "SFINAE" ne fonctionne pas

template <::std::size_t N, 
    typename = ::std::enable_if_t<N <= 0x17> 
> 
constexpr ::std::uint8_t const size_code = N; 

template <::std::size_t N, 
    typename = ::std::enable_if_t<(N > 0x17) && 
    (N <= ::std::numeric_limits<::std::uint8_t>::max()) 
    > 
> 
constexpr ::std::uint8_t const size_code = 0x18; 

template <::std::size_t N, 
    typename = ::std::enable_if_t< 
    (N > ::std::numeric_limits<::std::uint8_t>::max()) && 
    (N <= ::std::numeric_limits<::std::uint16_t>::max()) 
    > 
> 
constexpr ::std::uint8_t const size_code = 0x19; 

template <::std::size_t N, 
    typename = ::std::enable_if_t< 
    (N > ::std::numeric_limits<::std::uint16_t>::max()) && 
    (N <= ::std::numeric_limits<::std::uint32_t>::max()) 
    > 
> 
constexpr ::std::uint8_t const size_code = 0x1a; 

template <::std::size_t N, 
    typename = ::std::enable_if_t< 
    (N > ::std::numeric_limits<::std::uint32_t>::max()) && 
    (N <= ::std::numeric_limits<::std::uint64_t>::max()) 
    > 
> 
constexpr ::std::uint8_t const size_code = 0x1b; 
+0

Il ne faut pas évaluer à quoi que ce soit. Ce code est mal formé pour redéfinir plusieurs fois 'size_code'. –

+0

Vous feriez probablement mieux d'écrire une fonction 'constexpr' pour cela. – TartanLlama

+0

@ T.C. gcc bizarrerie, mais clang reconnaît cela. – user1095108

Répondre

3

Vous ne pouvez pas redéfinir des modèles de variables de ce type, votre code ne devrait donc pas fonctionner.

Ce serait beaucoup plus simple avec une fonction constexpr, quelque chose comme ceci:

template <typename T> constexpr T t_max = std::numeric_limits<T>::max(); 

constexpr std::uint8_t size_code (std::size_t n) { 
    if (n <= 0x17) return n; 
    if (n <= t_max<std::uint8_t>) return 0x18; 
    if (n <= t_max<std::uint16_t>) return 0x19; 
    if (n <= t_max<std::uint32_t>) return 0x1a; 
    if (n <= t_max<std::uint64_t>) return 0x1b; 
} 
1

Mes 2 cents:

template <::std::size_t N, typename = void> 
constexpr ::std::uint8_t const size_code{}; 

template <::std::size_t N> 
constexpr ::std::uint8_t const size_code<N, ::std::enable_if_t<N <= 0x17> > = N; 

template <::std::size_t N> 
constexpr ::std::uint8_t const size_code<N, 
    ::std::enable_if_t<(N > 0x17) && 
    (N <= ::std::numeric_limits<::std::uint8_t>::max()) 
    > 
> = 0x18; 

template <::std::size_t N> 
constexpr ::std::uint8_t const size_code<N, 
    ::std::enable_if_t< 
    (N > ::std::numeric_limits<::std::uint8_t>::max()) && 
    (N <= ::std::numeric_limits<::std::uint16_t>::max()) 
    > 
> = 0x19; 

template <::std::size_t N> 
constexpr ::std::uint8_t const size_code<N, 
    ::std::enable_if_t< 
    (N > ::std::numeric_limits<::std::uint16_t>::max()) && 
    (N <= ::std::numeric_limits<::std::uint32_t>::max()) 
    > 
> = 0x1a; 

template <::std::size_t N> 
constexpr ::std::uint8_t const size_code<N, 
    ::std::enable_if_t< 
    (N > ::std::numeric_limits<::std::uint32_t>::max()) && 
    (N <= ::std::numeric_limits<::std::uint64_t>::max()) 
    > 
> = 0x1b;