«Что случилось с моим SFINAE»?

Я новичок в написании кода метапрограммирования шаблонов (вместо того, чтобы просто его читать). Так что я сталкиваюсь с некоторыми проблемами с нубами. Один из которых довольно хорошо обобщен в этом посте, который не называется& quot; Что случилось с моим SFINAE? & quot;, который я буду C ++ 11-ize, как это:

(Note: I gave the methods different names only to help with my error diagnosis in this "thought experiment" example. See Заметки @ R.MartinhoFernandes о том, почему вы фактически не выбрали этот подход на практике для не перегруженных.)

#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 говорит, что то, что случилось со SFINAE, «это не было», и дает предложение, которое компилирует, но шаблонирует функции вместо класса. Это может быть правильным для некоторых ситуаций, но не для всех.(For instance: I'm specifically trying to write a container that can hold types that may or may not be copy-constructible, and I need to flip methods on and off based on that.)

В качестве обходного пути я дал этому шанс ... который, кажется, работает правильно.

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

Но если это не сломано(is it?)он, безусловно, не следует хорошей общей методологии для того, как включать и выключать методы в шаблонном классе, основанном на изучении типа для признаков. Есть ли лучшее решение?

Ответы на вопрос(2)

Ваш ответ на вопрос