«Что случилось с моим 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?)он, безусловно, не следует хорошей общей методологии для того, как включать и выключать методы в шаблонном классе, основанном на изучении типа для признаков. Есть ли лучшее решение?