首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编程模板的风格

问编程模板的风格
EN

Stack Overflow用户
提问于 2011-04-12 02:46:40
回答 5查看 103关注 0票数 0

如果有选择,你会选择哪一个?

代码语言:javascript
复制
template<class CheckEveryNode<true>>
struct X;

or 

template<bool CheckEveryNode>
struct X;

从设计者的角度来看,这并不是很明显,一方面我们在实际代码中具有可读性:

代码语言:javascript
复制
//taking first approach
//somewhere in the code
X<CheckEveryNode<false>> x;

在第二个方面,有更多的内容可以输入,有人会更喜欢:

代码语言:javascript
复制
//taking second approach
//somewhere in the code
X<false> x;//but here we don't really see immediately what the false means.  

所以,期待您的意见/建议

EN

回答 5

Stack Overflow用户

发布于 2011-04-12 03:08:59

由于经常涉猎元编程,我只能推荐一种“冗长”的方法,但我不太喜欢您提出的第一种方法。

理想情况下,在使用策略时,不只是传递一个标志,而是传递一个Policy对象,它允许用户随意定制它,而不是依赖于您自己的预定义的值。

例如:

代码语言:javascript
复制
struct NodeCheckerTag {};

struct CheckEveryNode {
  typedef NodeCheckerTag PolicyTag;
  void check(List const& list);
};

struct CheckFirstNode {
  typedef NodeCheckerTag PolicyTag;
  void check(List const& list);
};

template <typename Rand>
struct CheckSomeNodes {
  typedef NodeCheckerTag PolicyTag;
  CheckSomeNodes(Rand rand): _rand(rand) {}
  void check(List const& list);
  Rand _rand;
};

因此,您的类应该允许用户选择要选择的策略:

代码语言:javascript
复制
template <typename NodeChecker>
class X: NodeChecker // allow stateful implementation but let EBO kick in
{
};

PolicyTag用于存在以下几种策略:

代码语言:javascript
复制
template <typename NodeChecker, typename NodeAllocator, typename NodeNotifier>
class X;

你通常应该提供合理的默认值,但是总是有这样的情况,我想自定义最后一个!,通过切换到可变模板,你可以得到:

代码语言:javascript
复制
template <typename Tag, typename Default, typename... Policies>
struct PolicySelector
{
  typedef /**/ type;
};

template <typename... Policies>
class X: Policies...
{
  typedef typename PolicySelector<NodeCheckerTag, CheckNoNode,
    Policies...>::type NodeCheckerPolicy;
  typedef typename PolicySelector<NodeAllocatorTag, StdAllocator,
    Policies...>::type NodeAllocatorPolicy;
  ...
};

请注意,通过继承策略,如果您只关心调用某些函数,则可能不需要选择。只有当您需要隐藏在策略中的内部typedefs时,才有必要这样做,因为这些定义应该在派生类(这里是X)中显式地定义类型。

票数 2
EN

Stack Overflow用户

发布于 2011-04-12 02:56:05

第一

代码语言:javascript
复制
template<class CheckEveryNode<true>>
struct X;

将是错误的,它应该是

代码语言:javascript
复制
template<template<bool> CheckEveryNode>
struct X{};

这将需要您专门研究true或false条件:

代码语言:javascript
复制
// above is true case, below is false case
template<>
struct X<CheckEveryNode<false> >{};

或者通过以下方式使用部分专门化:

代码语言:javascript
复制
template<class CheckEveryNode>
struct X;

template<bool B>
struct X<CheckEveryNode<B> >{
  // real implementation
};

除此之外,第二个更容易实现,也更容易阅读,因为它是“如预期的”。当您提供模板参数时,您知道它的用途,不需要额外的结构。

票数 1
EN

Stack Overflow用户

发布于 2011-04-12 03:21:23

如果您关心的是当您有多个策略时会发生什么,并且您不知道各种布尔值的含义,那么您可以一起消除布尔值并使用标记。

代码语言:javascript
复制
struct CheckEvery { };
struct CheckNone { };

template<typename Check> struct Thingy;
template<> Thingy<CheckEvery> { ... };
template<> Thingy<CheckNone> { ... };

或者,您可以让策略指定要完成的工作,而不是专门化。

代码语言:javascript
复制
struct CheckEvery { bool shouldCheck(int) { return true; } };
struct CheckNone { bool shouldCheck(int) { return false; } };
struct CheckOdds { bool shouldCheck(int i) { return i % 2; } };

template<typename Checker> struct Thingy {
  Checker checker;
  void someFunction(int i) { if(checker.shouldCheck(i)) check(i); }
};

这个例子并没有得到很好的充实,但是它给了你一些启发。例如,您可能希望为Thingy构造函数提供一个Checker对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5625966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档