2

我一直在玩标签调度,下面的代码完全符合我的预期:

#include <type_traits>
#include <iostream>

void impl(std::true_type) { std::cout << "true\n"; }
void impl(std::false_type) { std::cout << "false\n"; }

template<typename T>
void dispatch(T&& val)
{
  impl(std::is_integral<typename std::remove_reference<T>::type>());
}

int main()
{
  dispatch(10);    // calls impl(std::true_type)
  dispatch("");    // calls impl(std::false_type)
}

但是如果我想否定这个条件,我就会遇到麻烦。我以为我可以!在里面的代码中扔一个“” dispatch

impl(!std::is_integral<T>());    // added "!"

但这不会编译。

我需要做什么才能使此代码正常工作?

4

4 回答 4

6

您可以实现operator !for (和std::integral_constant的基础类型):true_typefalse_type

template <typename T, T value>
inline constexpr std::integral_constant<T, !value>
operator ! (std::integral_constant<T, value>)
{ return {}; }

这似乎是可以轻松标准化的方便小东西之一。

于 2013-08-12T22:17:22.507 回答
5

std::integral_constant您可以像这样从 constexpr 值实例化 a :

 impl(std::integral_constant<bool, !std::is_integral<T>::value>());

std::true_type并且std::false_type实际上是这个类的别名。另一种方法是为此引入一个元函数

template <typename T>
struct not_ : std::integral_constant<bool, !T::value> {};

并使用(调用)它:

impl(typename not_<std::is_integral<T>>::type());

或使用类似的boost::mpl

于 2013-08-12T22:13:56.573 回答
1
std::false_type negate( std::true_type ) { return {}; }
std::true_type negate( std::false_type ) { return {}; }
impl(negate(std::is_integral<T>()));

或者,有点花哨:

template<typename T, T x>
std::integral_constant<T, !x> negate( std::integral_constant<T,x> ) { return {}; }
impl(negate(std::is_integral<T>()));

这延伸negate到所有integral_constants.

于 2013-08-13T14:01:24.613 回答
0

std::negation已在 C++17 中引入。

于 2021-01-27T09:03:15.437 回答