7 Stimmen

Kann ich boost::enable_if für eine Mitgliedsfunktion verwenden?

Ich schreibe eine Vorlagenklasse, und ich möchte eine zusätzliche Methode nur für einen bestimmten Vorlagentyp zulassen. Derzeit existiert die Methode für alle Vorlagentypen, verursacht aber einen Kompilierungsfehler für alle anderen Typen.

Erschwerend kommt hinzu, dass es sich um einen überladenen Operator() handelt. Ich bin nicht sicher, ob das, was ich tun möchte, hier tatsächlich möglich ist.

Hier ist, was ich jetzt habe:

template<typename T, typename BASE>
class MyClass  : public BASE
{
public:

    typename T& operator() (const Utility1<BASE>& foo);
    typename T const& operator() (const Utility2<BASE>& foo) const;
};

Ich möchte die T& Version immer verfügbar, aber die T const& Version nur verfügbar, wenn Utility2<BASE> gültig ist. Im Moment existieren beide Methoden, aber der Versuch, die const-Version zu verwenden, gibt einen seltsamen Kompilierungsfehler, wenn Utility2<BASE> ist ungültig. Ich hätte lieber eine sinnvolle Fehlermeldung oder sogar einen "no such member function"-Fehler.

Ist dies möglich?

EDITAR : Nach der Lektüre der Boost-Dokumente habe ich mir folgendes ausgedacht, und es scheint zu funktionieren:

template<typename T, typename BASE>
class MyClass  : public BASE
{
public:

    typename T& operator() (const Utility1<BASE>& foo);

    template<typename U>
    typename boost::enable_if<boost::is_same<Utility2<BASE>, U>, T>::type const &
    operator() (const U& foo) const;
};

Diese Methode existiert also nicht, es sei denn, jemand versucht, sie mit Utility2 zu verwenden, und er kann nur ein Utility2 erstellen, wenn es für diesen BASE-Typ gültig ist. Wenn sie aber nicht für diesen BASE-Typ gültig ist, verschwendet MyClass keine Zeit mit der Erstellung der Accessor-Methode.

4voto

Tim Punkte 8672

Ja, das ist möglich, aber nicht direkt mit dem Parameter der Klassenvorlage. boost::enable_if kann nur mit einem Template-Parameter in der Methode selbst verwendet werden. Also, mit ein wenig typedef Verwendung:

template<typename T, typename BASE>
class MyClass  : public BASE
{
public:
  typedef Utility2<BASE> util;

  typename T& operator() (const Utility1<BASE>& foo);

  template<typename U>
  typename boost::enable_if<boost::is_same<util, U>, T>::type const &
  operator() (const U& foo) const;
};

Das funktioniert, weil Utility2 nur aus einem bestimmten BASE-Typ erstellt werden kann. Wenn der BASE-Typ also ein anderer ist, wird die const-Version von operator() nicht existieren.

Es ist also eine sehr kleine Sache. Es bringt mir nicht viel. Aber es war schön, es zu tun.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X