O que aconteceu com o meu redu SFINAE: membros da classe de modelo condicional?
Eu sou novo em escrever código de metaprogramação de template (vs. apenas lê-lo). Então estou correndo contra alguns problemas noob. Uma delas é bem resumida por este post não chamado SO"O que aconteceu com o meu SFINAE?", que eu vou C ++ 11-ize como este:
(Nota: Eu dei os métodos nomes diferentes apenas para ajudar com o meu diagnóstico de erro neste exemplo "experimento de pensamento".@ Notas de R.MartinhoFernandes por que você não escolheria essa abordagem na prática para não sobrecargas.)
#include <type_traits>
using namespace std;
template <typename T>
struct Foo {
typename enable_if<is_pointer<T>::value, void>::type
valid_if_pointer(T) const { }
typename disable_if<is_pointer<T>::value, void>::type
valid_if_not_pointer(T) const { }
};
int main(int argc, char * argv[])
{
int someInt = 1020;
Foo<int*>().valid_if_pointer(&someInt);
Foo<int>().valid_if_not_pointer(304);
return 0;
}
@Alf diz que o que aconteceu com o SFINAE é "não estava lá em primeiro lugar", e dá uma sugestão que compila, mas modela as funções em vez da classe. Isso pode ser certo para algumas situações, mas não todas.(Por exemplo: Eu estou especificamente tentando escrever um contêiner que pode conter tipos que podem ou não ser construtíveis com a cópia, e eu preciso ativar e desativar os métodos com base nisso.)
Como uma solução alternativa, eu dei uma chance ... que parece funcionar corretamente.
#include <type_traits>
using namespace std;
template <typename T>
struct FooPointerBase {
void valid_if_pointer(T) const { }
};
template <typename T>
struct FooNonPointerBase {
void valid_if_not_pointer(T) const { }
};
template <typename T>
struct Foo : public conditional<
is_pointer<T>::value,
FooPointerBase<T>,
FooNonPointerBase<T> >::type {
};
int main(int argc, char * argv[])
{
int someInt = 1020;
#if DEMONSTRATE_ERROR_CASES
Foo<int*>().valid_if_not_pointer(&someInt);
Foo<int>().valid_if_pointer(304);
#else
Foo<int*>().valid_if_pointer(&someInt);
Foo<int>().valid_if_not_pointer(304);
#endif
return 0;
}
Mas se isso não for quebrado(é isso?), certamente não está seguindo uma boa metodologia geral de como ativar e desativar métodos em uma classe de modelo baseada no tipo sniffing para características. Existe uma solução melhor?