2013-02-12 12 views
6

Ich versuche, dies zu tun:bedingte (SFINAE) Überschreibung

struct A 
{ 
    virtual int f() const { return 0; } 
}; 

template <typename T> 
struct B : A 
{ 
    template <typename U = T, 
    typename std::enable_if<...some condition involving U...>::type> 
    int f() const { return 1; } 
}; 

Caveat, ich kann nicht Klassenvorlagen erben (verwenden statische Überschreibungen). Ist diese Art von Konstrukt erlaubt und kann das Template-Member B :: f() das Member A :: f() überschreiben?

Antwort

6

Versuchen Sie folgendes:

template <typename T, typename=void> 
struct B : A 
{ 
    ... 
}; 

temlate <typename T> 
struct B<T, typename std::enable_if<...some condition...>::type>: 
    A 
{ 
    virtual int f() const override { return 1; } 
}; 

, wo wir zwei Versionen von B<T> haben, eine, für die die Bedingung erfüllt ist (die enable_if eins), eine, für die die Bedingung falsch ist (die Standardeinstellung eins).

Wenn Sie in der Lage sein wollte, Ihre Standard-B Implementierung wiederzuverwenden, man könnte dies auch tun:

template <typename T, typename=void> 
struct B : A 
{ 
    ... 
}; 

template <typename T> 
struct B<T, typename std::enable_if<...some condition...>::type>: 
    B<T, bool> 
{ 
    virtual int f() const override { return 1; } 
}; 

, wo wir von der „falschen“ Fall in der „echten“ Fall erben. Aber das ist ein bisschen dreckig für mich - ich würde eher die allgemeine Implementierung in einen dritten Punkt (B_impl) statt diesen Hack setzen. (Dadurch können Sie auch statisch feststellen, dass das zweite Argument void im ersten Fall B ist).

+0

tolle Idee, funktioniert perfekt. – user1095108