Редактировать: Краткий ответ на мой вопрос заключается в том, что у меня было ошибочное представление о том, что может делать 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
struct Inter
{
void FuncA() { t.FuncA(); }
void FuncB() { t.FuncB(); }
T t;
};
// Always takes some sort of Inter.
template
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> finalA;
Final> finalB;
finalA.CallFuncs();
finalB.CallFuncs();
}
Обратите внимание, что в CallFuncs() всегда будут существовать и FuncA(), и FuncB(), но они могут не компилироваться в зависимости от типа T, используемого в Inter.Когда я пытался использовать ответ в приведенном выше связанном вопросе, он, казалось, всегда давал мне истину, и я предполагаю, что это только проверка того, что функция существует, а не то, что она действительно может быть скомпилирована (хотя я не могу исключить, что Я ничего не напутал...)
Для условного вызова функций, как я полагаю, я могу использовать enable_if как таковой:
template
typename std::enable_if< ! /* how to determine if FuncA can be called? */>::type TryCallFuncA( InterType& i )
{
}
template
typename std::enable_if* how to determine if FuncA can be called? */>::type TryCallFuncA( InterType& i )
{
i.FuncA();
}
template
typename std::enable_if< ! /* how to determine if FuncB can be called? */>::type TryCallFuncB( InterType& i )
{
}
template
typename std::enable_if* how to determine if FuncB can be called? */>::type TryCallFuncB( InterType& i )
{
i.FuncB();
}
template
struct Final
{
void CallFuncs()
{
TryCallFuncA(t);
TryCallFuncB(t);
}
InterType t;
};
но я не уверен, есть ли способ получить логическое значение для перейти в enable_if. Есть ли способ, которым я могу это сделать, или мне нужно вернуться к каким-то поддерживаемым вручную признакам типа, которые указывают, существуют ли функции?
Что касается доступного набора функций C++11, я использую MSVC 2010.
edit: Чтобы добавить важное примечание, в моей реальной ситуации реализация класса Inter является фактически непрозрачным в точке, где мне нужно определить, будет ли компилироваться Inter::FuncA/FuncB, поэтому я не могу просто всплывать дочерние типы и проверять наличие функции для них.