„Co się stało z moją SFINAE” redux: członkowie klas szablonów warunkowych?
Jestem nowy w pisaniu kodu metaprogramowania szablonu (a nie tylko po jego przeczytaniu). Więc mam problemy z noobem. Jeden z nich jest dość dobrze podsumowany przez ten post, który został napisany jako nie-SO„Co się stało z moją SFINAĄ?”, które będę C ++ 11-ize jak to:
(Uwaga: Dałem metodom różne nazwy tylko po to, by pomóc w diagnozie błędów w tym przykładzie „eksperymentu myślowego”. ZobaczNotatki @ R.MartinhoFernandes dlaczego w rzeczywistości nie wybierzesz takiego podejścia w przypadku braku przeciążenia.)
#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 mówi, że to, co stało się z SFINAE, to „Nie było go na pierwszym miejscu” i daje sugestię, która kompiluje, ale szablonuje funkcje zamiast klasy. To może być właściwe dla niektórych sytuacji, ale nie dla wszystkich.(Na przykład: Szczególnie próbuję napisać kontener, który może zawierać typy, które mogą lub nie mogą być konstruowane jako kopie, i muszę na tej podstawie włączać i wyłączać metody).
Jako obejście, dałem ten strzał ... który wydaje się działać poprawnie.
#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;
}
Ale jeśli to nie jest złamane(czy to?), z pewnością nie postępuje zgodnie z dobrą ogólną metodologią włączania i wyłączania metod w klasie z szablonami opartą na wąchaniu typu dla cech. Czy jest lepsze rozwiązanie?