Есть ли способ определить, существует ли функция и может ли она использоваться во время компиляции?

Edit: Короткий ответ на мой вопрос: у меня было ошибочное представление о том, что может делать SFINAE, и он вообще не проверяет тело функции:sfinae создает функциональное тело?

У меня есть проблема, похожая на эту:Можно ли написать шаблон для проверки существования функции?

Разница в том, что я хочу не только проверить, существует ли функция, но и узнать, действительно ли она пройдет SFINAE. Вот пример того, чего я пытаюсь достичь:

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

Обратите внимание, что в CallFuncs (), FuncA () и FuncB () всегда будут существовать, но они могут не компилироваться в зависимости от типа T, используемого в Inter. Когда я пытался использовать ответ в приведенном выше связанном вопросе, мне казалось, что он всегда дает мне истину, о которой я догадываюсь, потому что он только проверяет, существует ли функция, а не то, что она может быть скомпилирована (хотя я не могу править из-за того, что я что-то не испортил ...)

Для условного вызова функций, которые я представляю, я могу использовать enable_if как таковой:

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

но я не уверен, есть ли способ получить логическое значение для передачи в enable_if. Есть ли способ, которым я могу сделать это, или мне нужно прибегнуть к каким-то чертам типа, поддерживаемым вручную, которые указывают, существуют ли функции?

Что касается стоимости доступного набора функций C ++ 11, я использую MSVC 2010.

edit: Чтобы добавить важное примечание, в моей реальной ситуации реализация класса Inter фактически непрозрачна в момент, когда мне нужно определить, будет ли Inter :: FuncA / FuncB компилироваться, поэтому я не могу просто всплывать дочерние типы и проверьте наличие функции на них.

Ответы на вопрос(1)

Ваш ответ на вопрос