J'essaye de faire quelque chose comme ça:
#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;
}
mais j'obtiens cette erreur:
error: missing binary operator before token "("
Comment puis-je créer correctement le typedef conditionnel?
sizeof
autres constructions C ++. Il ne connaît certainement pas les choses avectypedef
lesquelles vous vous êtes créé , car cela n'a même pas encore été analysé.enable_if
ouconditional
pour définir conditionnellement des typedefs, mais vous ne pouvez pas utiliser de préprocesseur pour cela.sizeof
ne peut pas fonctionner dans les conditions d'un préprocesseur est que le langage est défini de cette façon, pas à cause du fonctionnement d'une implémentation.Réponses:
Utilisez la
std::conditional
méta-fonction de C ++ 11.Notez que si le type que vous utilisez
sizeof
est un paramètre de modèle, par exempleT
, vous devez utilisertypename
comme:Ou faites
Engine
dépendreT
comme:C'est flexible , car vous pouvez maintenant l'utiliser comme:
la source
sizeof(int) <= 4
n'est peut-être pas un moyen très portable puisque sur une machine Windows 64 bits, le compilateur GCC (MinGW) x64 donnesizeof(int) = sizeof(long) = 4
. Une meilleure façon seraitsizeof(void*) <= 4
.Engine<void*> engine4;
? ;-)std::conditional<sizeof(void*) <= 4, std::mt19937, std::mt19937_64>
dans le premier extrait de code.Engine<void*>
? : Pint
:)En utilisant,
std::conditional
vous pouvez le faire comme ceci:Si vous voulez faire un
typedef
, vous pouvez le faire aussi.la source
typename
iciSi vous n'avez pas C ++ 11 disponible (même si cela semble être le cas si vous prévoyez de l'utiliser
std::mt19937
), vous pouvez implémenter la même chose sans le support de C ++ 11 en utilisant la bibliothèque de métaprogrammation Boost (MPL) . Voici un exemple compilable:Cela imprime le nom mutilé de
foo
sur mon système, car ilint
fait 4 octets ici.la source
if_c
place? Il serait plus facile d'écrire doit (et comprendre):mpl::if_c<sizeof(int)<=4, foo, bar>::type
. N'est-ce pas?mpl::if_c
. J'ai mis à jour l'exemple pour utiliser cette approche à la place.