Я стремлюсь реализовать шаблон структуры, который можно использовать для определения того, является ли замена шаблона правильно сформированной или не удастся Примером использования является предоставление двух версий функций шаблона в зависимости от того, сопоставим ли параметр шаблона или нет.
Это может быть решено довольно легко, если предоставить структуры для каждого сценария явно, например существует ли оператор равенства для типа шаблона, как показано здесь . Но мне не удалось реализовать структуру, которая бы принимала (почти) произвольную конструкцию в качестве аргумента шаблона.
«Лучший» подход, которого я достиг, использует аргумент шаблона шаблона. Он компилируется, но не подходит для случая, когда подстановка аргумента должна быть правильно сформирована.
#include <iostream>
#include <type_traits>
template <typename T = void, typename...>
using Enable = T;
template <bool Cond, typename T = void>
using Enable_if = typename std::enable_if<Cond, T>::type;
template <typename T, template<typename> class X, typename = void>
struct Is_enabled : std::false_type {};
template <typename T, template<typename> class X>
struct Is_enabled<T, X, Enable<X<T>>> : std::true_type {};
/// An example of construct
template <typename T>
using Equals = decltype(std::declval<T>() == std::declval<T>());
template <typename T>
using Enabled_eq = Enable_if<Is_enabled<T, Equals>::value>;
template <typename T>
using Disabled_eq = Enable_if<!Is_enabled<T, Equals>::value>;
template <typename T>
Enabled_eq<T> foo()
{
std::cerr << "enabled!" << std::endl;
}
template <typename T>
Disabled_eq<T> foo()
{
std::cerr << "disabled!" << std::endl;
}
struct A {};
int main(int /*argc*/, const char* /*argv*/[])
{
foo<int>(); /// should print "enabled!"
foo<A>(); /// should print "disabled!"
return 0;
}
В случае int
он, очевидно, должен печатать "enabled!"
, а в случае A
он должен печатать "disabled!"
. Но он всегда печатает "disabled!"
, поэтому специализация Is_enabled
никогда не заканчивается.
Я немного близок к правильному решению или оно будет более сложным?