Czy jest jakiś sposób na wykrycie, czy dana funkcja istnieje i może być użyta w czasie kompilacji?

Edytować: Krótka odpowiedź na moje pytanie brzmi: pomyliłem się co do tego, co może zrobić SFINAE, i wcale nie sprawdza ciała funkcji:czy sfinae tworzy instancję funkcji?

Mam problem podobny do tego:Czy można napisać szablon, aby sprawdzić istnienie funkcji?

Różnica polega na tym, że chcę nie tylko sprawdzić, czy funkcja istnieje, ale także chcę wiedzieć, czy faktycznie przejdzie ona przez SFINAE. Oto przykład tego, co próbuję osiągnąć:

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();
}

Zauważ, że w CallFuncs () zarówno FuncA (), jak i FuncB () zawsze będą istnieć, ale mogą się nie kompilować w zależności od typu T używanego w Inter. Kiedy próbowałem użyć odpowiedzi w powyższym powiązanym pytaniu, wydawało mi się, że zawsze daje mi to do zrozumienia, co sądzę, ponieważ to tylko sprawdzenie, czy funkcja istnieje, a nie, że można ją faktycznie skompilować (chociaż nie mogę wykluczyć, że Nie coś zepsułem ...)

Aby warunkowo wywołać funkcje, które widzę, mogę użyć enable_if jako takiego:

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;
};

ale nie jestem pewien, czy w jakiś sposób mogę uzyskać wartość logiczną przekazaną do enable_if. Czy jest jakiś sposób, w jaki mogę to osiągnąć, czy muszę powrócić do pewnego rodzaju ręcznie utrzymywanych cech typu, które wskazują, czy funkcje istnieją?

Do tego, co jest warte, jeśli chodzi o dostępny zestaw funkcji C ++ 11, używam MSVC 2010.

edytować: Aby dodać ważną notatkę, w mojej rzeczywistej sytuacji implementacja klasy Inter jest efektywnie nieprzejrzysta w momencie, w którym muszę określić, czy Inter :: FuncA / FuncB będzie kompilował, więc nie mogę po prostu przesłonić typów potomnych i sprawdź, czy istnieje na nich funkcja.

questionAnswers(1)

yourAnswerToTheQuestion