SFINAE: static_assert vs std::enable_if

SFINAE: static_assert vs std::enable_if

本文关键字:enable if std assert static SFINAE vs      更新时间:2023-10-16

以下语法(建议!)有什么缺点吗?

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演绎

首先,它们是不同的,具体来说,它们不是同时检查的。

关键的区别是由于它们在过载解析方面的应用。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))
{ ... }

为什么使用static_assert比Concepts Lite语法更好?

template< typename T >
  void f() requires Int<T>()
  { }

或:

template< Int T >
  void f()
  { }