Existe alguma maneira de detectar se uma função existe e pode ser usada em tempo de compilação?
Editar: A resposta curta para a minha pergunta é que eu tinha uma visão errada do que a SFINAE pode fazer e não verifica o corpo da função:o sfinae instancia um corpo de função?
Eu tenho um problema semelhante a este:É possível escrever um modelo para verificar a existência de uma função?
A diferença é que eu quero não só verificar se a função existe, mas também quero saber se ela realmente passará SFINAE. Aqui está um exemplo do que estou tentando realizar:
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();
}
Observe que em CallFuncs (), FuncA () e FuncB () sempre existirão, mas eles não podem compilar dependendo do tipo T usado no Inter. Quando tentei usar a resposta na questão ligada acima, pareceu sempre dar-me a verdade, o que eu acho que é porque está apenas verificando se a função existe, não que ela possa ser compilada (embora eu não possa descartar isso Eu não estraguei nada ...)
Para chamar condicionalmente as funções que imagino, posso usar enable_if como tal:
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;
};
mas não tenho certeza se há alguma maneira de obter um valor booleano para passar para enable_if. Existe alguma maneira que eu possa realizar isso ou eu preciso voltar para algum tipo de traços de tipo mantidos manualmente que indicam se as funções existem?
Por que vale a pena até o conjunto de recursos C ++ 11 disponível, estou usando o MSVC 2010.
editar: Para adicionar uma nota importante, na minha situação atual a implementação da classe Inter é efetivamente opaca no ponto em que eu preciso determinar se o Inter :: FuncA / FuncB irá compilar ou não, então eu não posso apenas criar os tipos filhos e verifique a existência da função neles.