Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编程模板的风格_C++_Templates - Fatal编程技术网

C++ 编程模板的风格

C++ 编程模板的风格,c++,templates,C++,Templates,如果有选择,你会选择哪一个 template<class CheckEveryNode<true>> struct X; or template<bool CheckEveryNode> struct X; 模板 结构X; 或 模板 结构X; 从设计师的角度来看,这并不明显,一方面,我们在实际代码中具有可读性: //taking first approach //somewhere in the code X<CheckEveryNode<

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

template<class CheckEveryNode<true>>
struct X;

or 

template<bool CheckEveryNode>
struct X;
模板
结构X;
或
模板
结构X;
从设计师的角度来看,这并不明显,一方面,我们在实际代码中具有可读性:

//taking first approach
//somewhere in the code
X<CheckEveryNode<false>> x;
//采取第一种方法
//代码中的某个地方
X;
在第二方面,有更多的内容可供输入,有些人更喜欢:

//taking second approach
//somewhere in the code
X<false> x;//but here we don't really see immediately what the false means.  
//采取第二种方法
//代码中的某个地方
X//但在这里,我们并没有立即看到虚假的含义。

因此,期待您的意见/建议第一种方法看起来很麻烦。在第一个没有令人信服的理由的情况下,我会选择第二个。至于可读性,第二个是可读的。事实上,第一种方法由于语法混乱而降低了可读性。

第一种方法看起来很麻烦。在第一个没有令人信服的理由的情况下,我会选择第二个。至于可读性,第二个是可读的。事实上,第一个由于其hotchpotch语法而降低了可读性。

我也喜欢第二个。我的理念是,如果不需要,为什么还要创建一个额外的类型呢?

我也喜欢第二个。我的理念是,如果不需要,为什么要创建一个额外的类型?

首先

template<class CheckEveryNode<true>>
struct X;
模板
结构X;
这是错误的,应该是

template<template<bool> CheckEveryNode>
struct X{};
模板
结构X{};
这需要您专门研究正确或错误条件:

// above is true case, below is false case
template<>
struct X<CheckEveryNode<false> >{};
//以上为真,以下为假
模板
结构X{};
或按以下方式使用部分专门化:

template<class CheckEveryNode>
struct X;

template<bool B>
struct X<CheckEveryNode<B> >{
  // real implementation
};
模板
结构X;
模板
结构X{
//实际执行
};
除此之外,第二个更容易实现,也更容易阅读,因为它是“预期的”。当您提供模板参数时,您知道它的用途,不需要额外的结构。

首先

template<class CheckEveryNode<true>>
struct X;
模板
结构X;
这是错误的,应该是

template<template<bool> CheckEveryNode>
struct X{};
模板
结构X{};
这需要您专门研究正确或错误条件:

// above is true case, below is false case
template<>
struct X<CheckEveryNode<false> >{};
//以上为真,以下为假
模板
结构X{};
或按以下方式使用部分专门化:

template<class CheckEveryNode>
struct X;

template<bool B>
struct X<CheckEveryNode<B> >{
  // real implementation
};
模板
结构X;
模板
结构X{
//实际执行
};

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

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

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

例如:

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 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;
  ...
};
模板
结构策略选择器
{
typedef/**/type;
};
模板
第X类:政策。。。
{
typedef typename PolicySelector::type NodeCheckerPolicy;
typedef typename策略选择器::类型NodeLocatorPolicy;
...
};

请注意,通过从策略继承,如果您只关心调用某些函数,那么选择可能是不必要的。只有当您需要隐藏在策略中的内部typedef时才有必要,因为它们应该在派生类中显式定义(此处为X)。

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

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

例如:

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 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;
  ...
};
模板
结构策略选择器
{
typedef/**/type;
};
模板
第X类:政策。。。
{
typedef typename PolicySelector::type NodeCheckerPolicy;
typedef typename策略选择器::类型NodeLocatorPolicy;
...
};

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

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

struct CheckEvery { };
struct CheckNone { };

template<typename Check> struct Thingy;
template<> Thingy<CheckEvery> { ... };
template<> Thingy<CheckNone> { ... };
struct CheckEvery{};
结构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); }
};
struct CheckEvery{bool shouldCheck(int){return true;}};
结构CheckNone{bool shouldCheck(int){返回false;}};
结构校验概率{bool shouldCheck(inti){返回i%2;};
模板结构{
检查者;
void someFunction(inti){if(checker.shouldCheck(i))check(i);}
};

这个例子没有很好地充实,但它给了你一个想法。例如,您可能希望为
Thingy
构造函数提供一个
Checker
对象

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

struct CheckEvery { };
struct CheckNone { };

template<typename Check> struct Thingy;
template<> Thingy<CheckEvery> { ... };
template<> Thingy<CheckNone> { ... };
struct CheckEvery{};
结构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); }
};
struct CheckEve