这个模式的名字是什么?

时间:2011-09-08 19:30:03

标签: c++ templates design-patterns

我已经编写了一些模板类作为更大的模板类的一部分。一个允许我在类中包含或排除成员变量。另一个允许我生成传递的模板类参数或NOP而不是占位符。

这些允许类使用自己的模板参数通过单个非常通用的类定义来包含或排除数据成员,并且操作提供了一个防止类型不匹配问题的接口。

此代码示例显示了我正在使用的实现,因为我认为它在操作中更容易识别(与模式相关的类被称为“ghost”)。

typedef int field1type, field2type, field3type;

template <bool field1exists, bool field2exists, bool field3exists>
struct GhostShowcase
{
  typename Ghost<int, field1exists>::type intField;
  typename Ghost<float, field2exists>::type floatField;
  typename Ghost<char, field3exists>::type charField;
};

GhostShowcase<true,false,true> foo; // has int and char fields
                                    // but an unusable float field
GhostShowcase<true,true,true> bar; // has all fields usable

下面的示例显示了如何使用从ghost类派生的类型的运算符。测试函数printAll()使用ghostStaticOperator()来调用从GhostStaticOperation派生的类中的静态函数。此类是作为模板参数传递给GhostStaticOperation的类,或者是自动生成的类,它具有相同签名但不执行任何操作的静态函数。选择的类基于布尔模板参数exists。在main()中进行两次通话;第一个传递模板参数true,第二个传递false。

这些示例显示了可编译源(在g ++ 4.5.2中,设置了-std = c ++ 0x)。此文件可以命名为任何名称。

#include "ghost.h"
#include <iostream>
#include <functional>

using namespace Aryana;
using namespace std;

struct PrintingOperator : public std::unary_function<int, void>
{
  static inline void operation(int toPrint)
  {cout << toPrint;}
};

struct IncrementOperator : public std::unary_function<int&, void>
{
  static inline void operation(int& toIncrement)
  {++toIncrement;}
};

template <bool exists>
void printAll()
{
  typedef GhostStaticOperator<PrintingOperator, exists> printClass;
  typedef GhostStaticOperator<IncrementOperator, exists> incrClass;

  typename Ghost<int, exists>::type ghostObject;
  cout << "using ghost printer: ";
  ghostStaticOperation<printClass>(ghostObject);
  cout << "\nusing ghost incrementor...\n";
  ghostStaticOperation<incrClass>(ghostObject);
  cout << "using ghost printer: ";
  ghostStaticOperation<printClass>(ghostObject);
  cout << "\nfinished\n";
}

int main(int, char**)
{
  cout << "ghost operation with exists=true:\n";
  printAll<true>();
  cout << "ghost operation with exists=false:\n";
  printAll<false>();
}

此示例应命名为“ghost.h”,并与前一个文件放在同一目录中。

typedef char ghost_null_argument[0];
typedef void ghost_null_return;

template <class S, bool exists>
class Ghost;

template <class S, bool exists>
class GhostOperator;

template <class S, bool exists>
class GhostStaticOperator;

template <class S>
class Ghost<S, false>
{
  Ghost(); // private constructor to prevent instantiation
 public:
  typedef ghost_null_argument type;
  typedef S original_type;
};

template <class S>
class Ghost<S, true>
{
  Ghost(); // private constructor to prevent instantiation
 public:
  typedef S type;
  typedef S original_type;
};

template <class S, bool exists>
class GhostOperator;

template <class S>
class GhostStaticOperator<S, false>
{
  GhostStaticOperator(); // private constructor to prevent instantiation
 public:
  typedef ghost_null_return result_type;
  typedef ghost_null_argument argument_type;
  struct operator_type
  {
    inline static result_type operation(argument_type){};
  };
};

template <class S>
class GhostStaticOperator<S, true>
{
  GhostStaticOperator(); // private constructor to prevent instantiation
 public:
  typedef S operator_type;
  typedef typename operator_type::result_type result_type;
  typedef typename operator_type::argument_type argument_type;
};

// must define argument_type and result_type in the operator class
// result_type will be ghost_null_argument if the class is ghosting
template <class S>
inline
typename S::result_type ghostStaticOperation(typename S::argument_type argument)
{
  return S::operator_type::operation(argument);
}

1 个答案:

答案 0 :(得分:1)

我很确定这是“bug”模式。 char[0]不是有效的成员类型。

更严重的是,通常我们使用SFINAE直接检查可能存在或可能不存在的成员。这避免了整个Ghost<T, bool>模板。