Frage

Der ursprüngliche Titel war hier Behelfslösung für SFINAE Fehler in VS2005 C ++

Dies ist versuchsweise Verwendung von SFINAE das Äquivalent für die is_pod Template-Klasse zu machen, die in TR1 existiert (In VS2005 kein TR1 ist noch) nicht. Es sollte seine Wert Mitglied wahr haben, wenn die Template-Parameter ein POD-Typ (einschließlich primitiven Typen und Strukturen aus ihnen) und falsch ist, wenn es nicht (wie bei nicht-triviale Konstruktoren).

template <typename T> class is_pod
{
  public:

    typedef char Yes;
    typedef struct {char a[2];} No;

    template <typename C> static Yes test(int)
    {
      union {T validPodType;} u;
    }
    template <typename C> static No test(...)
    {
    }
    enum {value = (sizeof(test<T>(0)) == sizeof(Yes))};
};

class NonPOD
{
  public:
    NonPod(const NonPod &);
    virtual ~NonPOD();
};

int main()
{
  bool a = is_pod<char>::value;
  bool b = is_pod<NonPOD>::value;
  if (a) 
    printf("char is POD\n");
  if (b)
    printf("NonPOD is POD ?!?!?\n");
  return 0;
}

Das Problem ist nicht nur VS 2005 nicht TR1 haben, wird es nicht kümmern uns um die Vereinigung über (die nicht gültig sein sollte, wenn die Template-Parameter kein POD ist), so a und b bewerten zu wahr.


Danke für die Antworten unten geschrieben. Nach der Lektüre sorgfältig sie (und den Code) Ich erkennen, dass das, was ich war wirklich ein falscher Ansatz zu tun versuche. Die Idee war SFINAE Verhalten mit einer Anpassung an die Vorlage must_be_pod zu verbinden (was ich in dem Buch Imperfect C ++ , aber es kann in anderen Orten gefunden werden, auch). Eigentlich wäre dies eine ganz besondere Reihe von Regeln für SFINAE erfordern, die nicht sind, was die Norm definiert, offensichtlich. Das ist nicht wirklich ein Fehler in VS, nachdem alle.

War es hilfreich?

Lösung

Das größte Problem mit Ihrem Ansatz ist, dass Sie nicht tun SFINAE hier -. SFINAE gilt nur für Parametertypen und Rückkehr hier eingeben

Allerdings aller SFINAE Situationen im Standard gilt keine auf Ihre Situation. Sie sind

  • Arrays von Leere, Referenzen, Funktionen oder ungültiger Größe
  • Typ Element, das nicht eine Art
  • ist
  • Zeiger auf Referenzen, Verweise auf Verweise, Verweise auf void
  • Zeiger auf Mitglied einer Nicht-Klasse-Typ
  • ungültige Conversions von Template-Parameter Wert
  • Funktionstypen mit Argumenten vom Typ void
  • const / volatiler Funktionstyp

Das ist wahrscheinlich, warum in Boost-Dokumentation gibt es:

  

Ohne eine (noch nicht näher bezeichnet) Hilfe   vom Compiler, ispod nie   berichten, dass eine Klasse oder Struktur a   POD; dies ist immer sicher, wenn möglich   suboptimal. nur zur Zeit (Mai 2005)   MWCW 9 und Visual C ++ 8 die   notwendig Compiler-_intrinsics.

Andere Tipps

Dies ist auch nicht mit VS2008 arbeiten, aber ich vermute, dass Sie das auch wussten. Vorlage Argumente für Template-Parameter SFINAE ist für herzuleiten; Sie können nicht wirklich die Art von etwas ableiten, dass der Konstruktor-ness eines Typs zeigt, auch wenn Sie einen Typ erstellen können, die mit einer anderen Art unvereinbar ist (das heißt, können die Gewerkschaften nicht verwenden nicht-POD).

In der Tat, VS 2008 verwendet Compiler-Unterstützung für Züge std::tr1::type_traits zu implementieren.

Ich bin mir nicht sicher über die Art und Weise Sie versuchen SFINAE hier zu tun, da is_pod<T>::test(...) is_pod<T>::test(0) zu werden lassen. Vielleicht, wenn Sie eine andere Art anstelle von ‚int‘ verwenden würden Sie eine bessere Übereinstimmung bekommen:

template <typename T> class is_pod
{
  struct my_special_type { };
  public:
    typedef char Yes;
    typedef struct {char a[2];} No;

    template <typename C> static Yes test(my_special_type)
    {
      union {T validPodType;} u;
    }

    template <typename C> static No test(...)
    {
    }
    enum {value = (sizeof(test<T>(my_special_type())) == sizeof(Yes))};
};

Sie möchten vielleicht auch sehen Boost.Enable_i f Ihre SFINAE für Sie tun -. es sei denn, Sie versuchen, Ihre eigene Bibliothek oder aus irgendeinem Grund zu implementieren

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top