模板元函数组合 - 非案例

时间:2014-05-02 09:12:11

标签: c++ templates metaprogramming

假设我有一个元函数

   template<bool, class L, class R>
   struct IF
   {
       typedef R type; 
   };


   template <class L, class R>
   struct IF<true, L, R>
   {
     typedef L type; 
   };

我想要的是定义一个元函数Not,它将绑定到IF并返回'相反的状态'。到目前为止我所拥有的是:

template<bool Cond, typename L, typename R, template<bool, typename,typename> class MF>
struct Not
{
    typedef typename MF<!Cond, L, R>::type type;
};

这适用于这种特殊情况。我的问题是:

  1. 有没有办法提供更通用的解决方案? (关于我们正在扩展的元函数的参数和功能)
  2. 在C ++中有没有经过验证的设计/习语/模式来做这些事情
  3. 我怀疑可以使用boost::mpl完成此操作。任何人都可以提供一个例子吗?

2 个答案:

答案 0 :(得分:5)

我能提出的最通用的解决方案适用于任何类模板,其中包含bool和任意数量的类型参数 - 包括std::enable_if

template<template<bool, typename...> class T, bool arg1, typename... args>
struct Not : T<!arg1, args...> { };

简单的用法是:

struct bacon {
    static const bool tasty = true;
    static std::string name() { return "bacon"; }
};

struct spinach {
    static const bool tasty = false;
    static std::string name() { return "spinach"; }
};

template<typename Food>
typename std::enable_if<Food::tasty>::type eat()
{
    ::std::cout << "Yummy! " << Food::name() << "!\n";
}

template<typename Food>
typename Not<std::enable_if, Food::tasty, void>::type eat()
{
    ::std::cout << "Yuck! " << Food::name() << "!\n";
}

和测试用例

eat<bacon>();
eat<spinach>();

会通知您bacon很好吃,而spinach却没有。

答案 1 :(得分:1)

您可以使用单个参数制作非模板:

#include <iostream>

template<bool, class L, class R>
struct IF
{
    typedef R type;
};

template <class L, class R>
struct IF<true, L, R>
{
    typedef L type;
};


template<typename MF>
struct Not;

template<bool Cond, typename L, typename R, template<bool, typename, typename> class MF>
struct Not<MF<Cond, L, R>>
{
    typedef typename MF<!Cond, L, R>::type type;
};

struct A { static void print() { std::cout << "A\n"; } };
struct B { static void print() { std::cout << "B\n"; } };

int main()
{
    IF<true, A, B>::type::print();
    Not<IF<true, A, B>>::type::print();
    return 0;
}