Estou tentando obter um exemplo simples para entender como usar std::enable_if
. Depois de ler esta resposta , pensei que não seria muito difícil criar um exemplo simples. Eu quero usar std::enable_if
para escolher entre duas funções-membro e permitir que apenas uma delas seja usada.
Infelizmente, o seguinte não é compilado com o gcc 4.7 e, após horas e horas de tentativas, estou perguntando a vocês qual é o meu erro.
#include <utility>
#include <iostream>
template< class T >
class Y {
public:
template < typename = typename std::enable_if< true >::type >
T foo() {
return 10;
}
template < typename = typename std::enable_if< false >::type >
T foo() {
return 10;
}
};
int main() {
Y< double > y;
std::cout << y.foo() << std::endl;
}
O gcc relata os seguintes problemas:
% LANG=C make CXXFLAGS="-std=c++0x" enable_if
g++ -std=c++0x enable_if.cpp -o enable_if
enable_if.cpp:12:65: error: `type' in `struct std::enable_if<false>' does not name a type
enable_if.cpp:13:15: error: `template<class T> template<class> T Y::foo()' cannot be overloaded
enable_if.cpp:9:15: error: with `template<class T> template<class> T Y::foo()'
Por que o g ++ não exclui a instanciação incorreta para a segunda função de membro? De acordo com o padrão, std::enable_if< bool, T = void >::type
só existe quando o parâmetro do modelo booleano é verdadeiro. Mas por que o g ++ não considera isso como SFINAE? Eu acho que a mensagem de erro de sobrecarga vem do problema de que o g ++ não exclui a segunda função de membro e acredita que isso deve ser uma sobrecarga.
std::is_same< T, int >::value
e ! std::is_same< T, int >::value
que dá o mesmo resultado.