“¿Qué le sucedió a mi SFINAE” redux: miembros de la clase de plantilla condicional?

Soy nuevo en escribir código de metaprogramación de plantillas (frente a solo leerlo). Así que estoy en conflicto con algunos problemas de noob. Uno de los cuales está bastante bien resumido en esta publicación no SO llamada"¿Qué le pasó a mi SFINAE?", lo cual haré con C ++ 11 como este:

(Nota: Le di a los métodos diferentes nombres solo para ayudar con mi diagnóstico de errores en este ejemplo de "experimento mental". VerNotas de R.MartinhoFernandes ¿Por qué no elegiría este enfoque en la práctica para las no 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 dice que lo que le pasó al SFINAE es "No estaba allí en primer lugar", y da una sugerencia que compila, pero las funciones de las plantillas en lugar de la clase. Eso podría ser correcto para algunas situaciones, pero no todas.(Por ejemplo: estoy tratando específicamente de escribir un contenedor que pueda contener tipos que puedan o no ser construibles por copia, y necesito activar y desactivar los métodos según eso).

Como solución alternativa, le di a esta una oportunidad ... que parece funcionar correctamente.

#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;
}

Pero si esto no está roto(¿Lo es?)Sin duda, no está siguiendo una buena metodología general sobre cómo activar y desactivar los métodos en una clase de plantilla basada en la detección del tipo de rasgos. ¿Hay una solución mejor?

Respuestas a la pregunta(2)

Su respuesta a la pregunta