Я изучаю SFINAE и трейты, и я знаю, что могу определять черты, связанные с SFINAE (трейты, которые используют SFINAE в своей реализации). Классическая реализация c признака, которая определяет, является ли тип конструктивным по умолчанию:
template <typename T>
struct IsDefaultConstructibleH
{
private:
template <typename U, typename = decltype(U())>
//template <typename U, const U& = U()> // WHY IS THIS ALWAYS SFINAE'd out?
static TrueType Test(void*);
template <typename>
static FalseType Test(...);
public:
using Type = decltype(Test<T>(nullptr));
};
template <typename T>
struct IsDefaultConstructible : IsDefaultConstructibleH<T>::Type
{
};
template <typename T>
constexpr bool IsDefaultConstructibleV = IsDefaultConstructible<T>::Value;
Как я указал в приведенном выше коде, если я использую закомментированное предложение параметризации шаблона (и комментарий -из вышеприведенного), если я запустил этот код:
#include "traits.hpp"
#include <iostream>
class Default
{
public:
Default() : mData(10) {}
private:
int mData;
};
class NoDefault
{
public:
NoDefault(int i) : mData(i) {}
private:
int mData;
};
int main(int argc, char ** argv)
{
std::cout << std::boolalpha << IsDefaultConstructible<Default>::Value << std::endl;
std::cout << std::boolalpha << IsDefaultConstructibleV<NoDefault> << std::endl;
return 0;
}
, результат всегда будет false false, тогда как если я использую другое предложение параметризации (то, которое не закомментировано), программа дает истина, ложь, как и ожидалось. Так почему же в предложении с параметром, не являющимся типом, всегда выводится SFINAE?