Gibt es eine Möglichkeit zu erkennen, ob eine Funktion vorhanden ist und zur Kompilierungszeit verwendet werden kann?

Bearbeiten: Die kurze Antwort auf meine Frage ist, dass ich eine falsche Vorstellung davon hatte, was SFINAE kann, und dass es den Funktionskörper überhaupt nicht überprüft:instanziiert sfinae einen funktionskörper?

Ich habe ein ähnliches Problem:Ist es möglich, eine Vorlage zu schreiben, um die Existenz einer Funktion zu überprüfen?

Der Unterschied besteht darin, dass ich nicht nur prüfen möchte, ob die Funktion vorhanden ist, sondern auch wissen möchte, ob sie tatsächlich SFINAE besteht. Hier ist ein Beispiel dafür, was ich versuche zu erreichen:

struct A
{
    void FuncA() { std::cout << "A::FuncA" << std::endl; }
};

struct B
{
    void FuncA() { std::cout << "B::FuncA" << std::endl; }
    void FuncB() { std::cout << "B::FuncB" << std::endl; }
};

template<typename T>
struct Inter
{
    void FuncA() { t.FuncA(); }
    void FuncB() { t.FuncB(); }

    T t;
};

// Always takes some sort of Inter<T>.
template<typename InterType>
struct Final
{
    void CallFuncs()
    {
        // if( t.FuncA() exists and can be called )
            t.FuncA();

        // if( t.FuncB() exists and can be called )
            t.FuncB();
    }

    InterType t;
};

void DoEverything()
{
    Final<Inter<A>> finalA;
    Final<Inter<B>> finalB;

    finalA.CallFuncs();
    finalB.CallFuncs();
}

Beachten Sie, dass in CallFuncs () sowohl FuncA () als auch FuncB () immer vorhanden sind, sie jedoch je nach dem in Inter verwendeten Typ T möglicherweise nicht kompiliert werden. Als ich versuchte, die Antwort in der oben verlinkten Frage zu verwenden, schien es mir immer wahr zu sein, was ich vermute, weil es nur prüft, ob die Funktion existiert, nicht, dass sie tatsächlich kompiliert werden kann (obwohl ich das nicht ausschließen kann Ich habe nichts vermasselt ...)

Um die von mir angegebenen Funktionen bedingt aufzurufen, kann enable_if wie folgt verwendet werden:

template<typename InterType>
typename std::enable_if< ! /* how to determine if FuncA can be called? */>::type TryCallFuncA( InterType& i )
{
}
template<typename InterType>
typename std::enable_if</* how to determine if FuncA can be called? */>::type TryCallFuncA( InterType& i )
{
    i.FuncA();
}

template<typename InterType>
typename std::enable_if< ! /* how to determine if FuncB can be called? */>::type TryCallFuncB( InterType& i )
{
}
template<typename InterType>
typename std::enable_if</* how to determine if FuncB can be called? */>::type TryCallFuncB( InterType& i )
{
    i.FuncB();
}

template<typename InterType>
struct Final
{
    void CallFuncs()
    {
        TryCallFuncA(t);
        TryCallFuncB(t);
    }

    InterType t;
};

Ich bin mir jedoch nicht sicher, ob es eine Möglichkeit gibt, einen booleschen Wert an enable_if zu übergeben. Gibt es eine Möglichkeit, dies zu erreichen, oder muss ich auf manuell gepflegte Typmerkmale zurückgreifen, die angeben, ob die Funktionen vorhanden sind?

Soweit es die verfügbaren C ++ 11-Funktionen wert sind, verwende ich MSVC 2010.

bearbeiten: Um einen wichtigen Hinweis hinzuzufügen: In meiner aktuellen Situation ist die Implementierung der Klasse Inter an dem Punkt, an dem ich bestimmen muss, ob Inter :: FuncA / FuncB kompiliert werden soll, praktisch undurchsichtig, sodass ich die untergeordneten Typen nicht einfach in die Luft sprudeln kann und überprüfen Sie, ob die Funktion auf ihnen vorhanden ist.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage