如果有选择,你会选择哪一个?
template<class CheckEveryNode<true>>
struct X;
or
template<bool CheckEveryNode>
struct X;从设计者的角度来看,这并不是很明显,一方面我们在实际代码中具有可读性:
//taking first approach
//somewhere in the code
X<CheckEveryNode<false>> x;在第二个方面,有更多的内容可以输入,有人会更喜欢:
//taking second approach
//somewhere in the code
X<false> x;//but here we don't really see immediately what the false means. 所以,期待您的意见/建议
发布于 2011-04-12 03:08:59
由于经常涉猎元编程,我只能推荐一种“冗长”的方法,但我不太喜欢您提出的第一种方法。
理想情况下,在使用策略时,不只是传递一个标志,而是传递一个Policy对象,它允许用户随意定制它,而不是依赖于您自己的预定义的值。
例如:
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;
};因此,您的类应该允许用户选择要选择的策略:
template <typename NodeChecker>
class X: NodeChecker // allow stateful implementation but let EBO kick in
{
};PolicyTag用于存在以下几种策略:
template <typename NodeChecker, typename NodeAllocator, typename NodeNotifier>
class X;你通常应该提供合理的默认值,但是总是有这样的情况,我想自定义最后一个!,通过切换到可变模板,你可以得到:
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)中显式地定义类型。
发布于 2011-04-12 02:56:05
第一
template<class CheckEveryNode<true>>
struct X;将是错误的,它应该是
template<template<bool> CheckEveryNode>
struct X{};这将需要您专门研究true或false条件:
// above is true case, below is false case
template<>
struct X<CheckEveryNode<false> >{};或者通过以下方式使用部分专门化:
template<class CheckEveryNode>
struct X;
template<bool B>
struct X<CheckEveryNode<B> >{
// real implementation
};除此之外,第二个更容易实现,也更容易阅读,因为它是“如预期的”。当您提供模板参数时,您知道它的用途,不需要额外的结构。
发布于 2011-04-12 03:21:23
如果您关心的是当您有多个策略时会发生什么,并且您不知道各种布尔值的含义,那么您可以一起消除布尔值并使用标记。
struct CheckEvery { };
struct CheckNone { };
template<typename Check> struct Thingy;
template<> Thingy<CheckEvery> { ... };
template<> Thingy<CheckNone> { ... };或者,您可以让策略指定要完成的工作,而不是专门化。
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对象。
https://stackoverflow.com/questions/5625966
复制相似问题