如何否定std :: is_integral用于标签调度?

时间:2013-08-12 22:10:12

标签: c++ c++11 template-meta-programming

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

#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 个答案:

答案 0 :(得分:5)

您可以从constexpr值中实例化std::integral_constant,如下所示:

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

std::true_typestd::false_type实际上是此类的别名。另一种方法是为此引入metafunction

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

并使用(调用)它:

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

或使用boost::mpl

中的类似内容

答案 1 :(得分:5)

您可以为operator !std::integral_constanttrue_type的基础类型)实施false_type

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

这似乎是那些易于标准化的便捷小事之一。

答案 2 :(得分: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

答案 3 :(得分:0)

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