Ответ 1
Почему использование static_assert
лучше, чем синтаксис Concepts Lite?
template< typename T >
void f() requires Int<T>()
{ }
или
template< Int T >
void f()
{ }
Есть ли недостатки в следующем синтаксисе Предлагаемый!?
template< typename T >
void f() static_assert(std::is_same< T, int >::value)
{ ; }
вместо SFINAE (это выглядит как костыль):
template< typename T, typename = typename std::enable_if< std::is_same< T, int >::value >::type >
void f() { ; }
или даже хуже:
template< typename T >
typename std::enable_if< std::is_same< T, int >::value >::type
f()
{ ; }
который запрещает использование вывода auto
типа результата.
Почему использование static_assert
лучше, чем синтаксис Concepts Lite?
template< typename T >
void f() requires Int<T>()
{ }
или
template< Int T >
void f()
{ }
Прежде всего, они разные, в частности, они не проверяются в одно и то же время.
Критическое различие связано с их применением в отношении разрешения перегрузки. SFINAE будет отбирать функции из набора перегрузки, так что будет выбрана другая функция (если есть), тогда как static_assert
применяется после разрешения перегрузки и, таким образом, даст ошибку, которая прекратит компиляцию.
Теперь, в отношении вашей жалобы, вы можете отлично использовать auto
и SFINAE:
// Ensure that T is int
template <typename T>
auto f() -> typename std::enable_if< std::is_same< T, int >::value >::type
{ ... }
// Only pick this overload if begin(c) and end(c) are available
template <typename T>
auto f(T const& c) -> decltype(begin(c), end(c), bool{}) { ... }
... и вы можете использовать SFINAE и автоматический вывод типа
template <typename T,
typename = typename std::enable_if<std::is_same<T, int>::value>::type>
auto f() { ... }
template <typename T>
auto f(void* =
typename std::enable_if<std::is_same<T, int>::value>::type*(0))
{ ... }