Ich versuche so etwas zu tun:
#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;
}
aber ich bekomme diesen Fehler:
error: missing binary operator before token "("
Wie kann ich das bedingte typedef korrekt erstellen?
sizeof
oder andere C ++ - Konstrukte. Es weiß sicherlich nichts über Dinge, mit denen Sie sich selbst erstellt habentypedef
, da dies noch nicht einmal analysiert wurde.enable_if
oderconditional
bedingt definieren, aber Sie können dafür keinen Präprozessor verwenden.sizeof
unter Präprozessorbedingungen nicht funktionieren kann, liegt darin, dass die Sprache auf diese Weise definiert ist und nicht daran, wie eine Implementierung funktioniert.Antworten:
Verwenden Sie die
std::conditional
Metafunktion aus C ++ 11.Beachten Sie, dass Sie, wenn der Typ, in dem Sie verwenden,
sizeof
beispielsweise ein Vorlagenparameter ist, FolgendesT
verwenden müssentypename
:Oder machen Sie
Engine
abhängig vonT
:Das ist flexibel , denn jetzt können Sie es verwenden als:
quelle
sizeof(int) <= 4
ist möglicherweise keine sehr portable Methode, da auf einem 64-Bit-Windows-Computer der GCC (MinGW) x64-Compiler dies ermöglichtsizeof(int) = sizeof(long) = 4
. Ein besserer Weg wäresizeof(void*) <= 4
.Engine<void*> engine4;
? ;-)std::conditional<sizeof(void*) <= 4, std::mt19937, std::mt19937_64>
im ersten Code-Snippet.Engine<void*>
? : Pint
:)Mit
std::conditional
können Sie es so machen:Wenn Sie eine machen wollen
typedef
, können Sie das auch machen.quelle
typename
hierWenn Sie nicht über C ++ 11 verfügen (obwohl dies anscheinend der Fall ist, wenn Sie dies planen
std::mt19937
), können Sie dasselbe mithilfe der Boost Metaprogramming Library (MPL) ohne C ++ 11-Unterstützung implementieren . Hier ist ein kompilierbares Beispiel:Dies gibt den verstümmelten Namen von
foo
auf meinem System aus, daint
hier 4 Bytes sind.quelle
if_c
stattdessen? Es wäre einfacher zu schreiben (und zu verstehen) :mpl::if_c<sizeof(int)<=4, foo, bar>::type
. Ist es nicht?mpl::if_c
. Ich habe das Beispiel aktualisiert, um stattdessen diesen Ansatz zu verwenden.