Есть ли способ определить, существует ли функция и может ли она использоваться во время компиляции?
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 компилироваться, поэтому я не могу просто всплывать дочерние типы и проверьте наличие функции на них.