2012-12-25 2 views
9

Angenommen, ich möchte die Einschränkung erzwingen, dass der übergebene Template-Parameter ein Kind von Foo ist.Wie erzwingen Kind-of-X-Beschränkung für Vorlagenparameter?

Gibt es eine Möglichkeit, dies durch Typ-Züge zu erzwingen? Ein Kompilierungsfehler static_assert wäre großartig.

In dem Code unten, machen wir es eine zweiteilige (separate) Frage.

  1. Lassen Sie nur My_Limited_Template<Bar> kompilieren.
  2. Lassen Sie nur My_Limited_Template<TBar> kompilieren.

EDIT ich für die schlechte Namensgebung entschuldigen: TBar und TBaz sollen Nicht-Template-Klassen auf Zwecke sein. Ich lege T nur vor dem Namen aus den Klassen in Teil eindeutig zu machen 1.

CODE

struct Foo { };    // no 
struct Bar : public Foo { }; // yes 
struct Baz { };    // no 

template< typename T > 
struct TFoo { };      // no 
struct TBar : public TFoo<TBar> { }; // yes 
struct TBaz { };      // no 

template< typename T > 
struct My_Limited_Template 
{ 
    // Part One: 
    // My_Limited_Template<Foo> // disallow 
    // My_Limited_Template<Bar> // allow 
    // My_Limited_Template<Baz> // disallow 
    // 
    // Part Two: 
    // My_Limited_Template<TFoo<int>> // disallow 
    // My_Limited_Template<TBar>  // allow 
    // My_Limited_Template<TBaz>  // disallow 
}; 
+1

So ist der zweite Teil würde * werden „nur Parameter ermöglichen, die von TFoo abgeleitet werden unter Verwendung CRTP“ *? – jrok

+0

@jrok +1 wenn du CRTP mit einbeziehen könntest, wäre das noch besser, aber ich bin mir nicht sicher, ob das möglich ist! – kfmfe04

+0

Was ich meinte ist, dass ** Sie ** CRTP verwendet haben, wenn Sie TBar ableiten. Ist das die einzige Art von 'TFoo'-Kind, das du erlauben willst oder ist es in Ordnung, etwas wie 'struct X: TFoo {};'? – jrok

Antwort

1

Ich gehe davon aus, dass Sie einen Fehler bei der Definition von TBar und TBas gemacht, überprüfen, ob meine Modifikation ist richtig.

#include <type_traits>  

struct Foo { };    // don't allow this 
struct Bar : public Foo { }; // allow this 
struct Baz { };    // don't allow this 

template< typename T > struct TFoo { };      
template< typename T > struct TBar : public TFoo<TBar<T>> { }; 
template< typename T > struct TBaz { };      

template< typename T > 
struct My_Limited_Template 
{ 
     static_assert(
       (std::is_base_of<Foo,T>::value && !std::is_same<T,Foo>::value) 
       || 
       (std::is_base_of<TFoo<T>,T>::value && !std::is_same<T,TFoo<T>>::value), 
       "fail2" 
     ); 
}; 
+1

Ich glaube nicht, dass Ihr zweiter Teil richtig ist (warum gehen Sie davon aus, dass die Frage falsch ist?). IIUC, erfordert die Frage, dass "T" eine Unterklasse einer (nicht näher bezeichneten) Instanziierung von "TFoo" ist, während Ihre Antwort erfordert, dass "T" eine Unterklasse von speziell "TFoo " ist. – Mankarse

Verwandte Themen