Sto compilando un codice con clangore 3.3 che sembra per compilare bene con gcc 4.8:clang 3.3 e constexpr vincoli
Il codice originale è stato:
template <std::size_t N> struct helper { typedef void type; };
template <> struct helper<64> { typedef int64_t type; };
template <> struct helper<32> { typedef int32_t type; };
template <> struct helper<16> { typedef int16_t type; };
template <> struct helper<8> { typedef int8_t type; };
template <std::size_t I, std::size_t F>
struct test
{
typedef typename helper<I+F>::type value_type;
static constexpr std::size_t frac_mask = ~((~value_type(0)) << F);
};
In clang, se tento di dichiarare Test < 16,16> o il test < 8,0> ottengo l'errore:
test.cpp:41:34: error: constexpr variable 'frac_mask' must be initialized by a constant expression
static constexpr std::size_t frac_mask = ~((~value_type(0)) << F);
gioco intorno con esso, se posso convertire il codice a:
C'è alcune regole -test.cpp:23:36: error: constexpr variable 'frac_mask' must be initialized by a constant expression
test.cpp:66:15: note: in instantiation of template class 'test<8, 0>' requested here
test.cpp:23:66: note: left shift of negative value -1
static constexpr mask_type frac_mask = ~((~mask_type(0)) << F);
La mia domanda è:
template <std::size_t I, std::size_t F>
struct test
{
typedef typename helper<I+F>::type value_type;
typedef typename std::make_unsigned<value_type>::type mask_type;
static constexpr mask_type frac_mask = ~((~mask_type(0)) << F);
};
Compila nella maggior parte dei casi (valori di I, F), ma se dichiaro di prova < 8, 0>, ottengo l'errore Sto violando qui in termini di specifiche di constexpr? Inoltre, per l'ultimo errore - il tipo di maschera è senza segno - si tratta di un problema del compilatore che pensa che io stia spostando un valore negativo o sto leggendo male il codice?
possibile duplicato di [Calling constexpr nell'argomento modello predefinito] (http://stackoverflow.com/questions/10721130/calling-constexpr-in-default-template-argument) –
Immettere le regole di promozione convertendo il tuo uint8_t in int, che è firmato? –