Estou tentando fazer algo assim:
#include <iostream>
#include <random>
typedef int Integer;
#if sizeof(Integer) <= 4
typedef std::mt19937 Engine;
#else
typedef std::mt19937_64 Engine;
#endif
int main()
{
std::cout << sizeof(Integer) << std::endl;
return 0;
}
mas recebo este erro:
error: missing binary operator before token "("
Como posso fazer corretamente o typedef condicional?
sizeof
, ou outras construções C ++. Ele certamente não sabe sobre coisas que você mesmo criou comtypedef
, como que nem sequer foi ainda analisado.enable_if
ouconditional
definir condicionalmente typedefs, mas não pode usar o pré-processador para isso.sizeof
não pode funcionar em condições de pré-processador é porque a linguagem é definida dessa forma, não por causa de como uma implementação funciona.Respostas:
Use a
std::conditional
meta-função do C ++ 11.Observe que se o tipo que você usa em
sizeof
for um parâmetro de modelo, digamosT
, você deve usartypename
como:Ou faça
Engine
depender deT
como:Isso é flexível , porque agora você pode usá-lo como:
fonte
sizeof(int) <= 4
talvez não seja uma forma muito portátil, já que em uma máquina Windows de 64 bits, o compilador GCC (MinGW) x64 oferecesizeof(int) = sizeof(long) = 4
. A melhor maneira seriasizeof(void*) <= 4
.Engine<void*> engine4;
? ;-)std::conditional<sizeof(void*) <= 4, std::mt19937, std::mt19937_64>
no primeiro trecho de código.Engine<void*>
? : Pint
:)Usando
std::conditional
você pode fazer assim:Se quiser fazer um
typedef
, você também pode fazer isso.fonte
typename
aquiSe você não tiver o C ++ 11 disponível (embora pareça que sim se estiver planejando usar
std::mt19937
), você pode implementar a mesma coisa sem o suporte do C ++ 11 usando a Boost Metaprogramming Library (MPL) . Aqui está um exemplo compilável:Isso imprime o nome mutilado de
foo
no meu sistema, pois umint
tem 4 bytes aqui.fonte
if_c
vez disso? Seria obrigação mais fácil de escrever (e entender):mpl::if_c<sizeof(int)<=4, foo, bar>::type
. Não é?mpl::if_c
. Atualizei o exemplo para usar essa abordagem.