【问题标题】:Adding methods to class template specialization向类模板特化添加方法
【发布时间】:2019-02-24 10:51:45
【问题描述】:

我想实现 STL 中存在的行为:当我们查看向量容器时,已知它具有 vector<bool> 特化,它添加了方法 flip()

是否可以在不将整个类复制为特化并在其主体中添加新方法的情况下实现此类扩展?

【问题讨论】:

  • 你可以使用从 stl::vector 继承
  • 不,不 - 我想扩展我自己的课程,vector<bool> 只是一个例子。我的课与向量无关,但我想根据类型有不同的方法。

标签: c++ templates stl template-specialization


【解决方案1】:

我想您可以编写特化,使其继承通用版本。

例如:假设你有一个struct foo,带有一个类型和一个值(带有默认值)模板参数;假设它有一些方法(bar(),在下面的例子中)

template <typename, bool = true>
struct foo 
 { void bar () {}; };

并假设您想要使用相同的方法和额外的baz()bool(作为模板类型)进行专门化;您可以从通用版本继承foo&lt;bool&gt;,如下所示

template <>
struct foo<bool> : public foo<bool, false>
 { void baz () {}; };

你可以验证

   foo<int>   fi;

   fi.bar();   // compile
   //fi.baz(); // compilation error

   foo<bool>  fb;

   fb.bar();  // compile
   fb.baz();  // compile

【讨论】:

  • 这很棒,我会记住的,但我认为@Jarod42 的答案更优雅。不过,非常感谢!
  • 我有一个问题 - bool = true 在模板规范中做了什么?
  • @KONAKONA - 哦,是的:Jarod42 的解决方案非常好。 bool = true 声明第二个模板参数,bool 类型的值,默认值 (true);所以当你定义foo&lt;bool&gt; 时,你就是在定义foo&lt;bool, true&gt;。我使用第二个模板参数从通用版本继承,为第一个模板参数维护相同的类型 (bool)。
  • 顺便说一句,在 C++20 之前,我更喜欢这个的变体:template &lt;typename T&gt; struct foo : foo_baz&lt;T&gt; {/*..*/};foo_baz&lt;T&gt; 为空,foo_baz&lt;bool&gt; 的特化。
【解决方案2】:

你可以SFINAE“专业化”的方法

template <typename T>
class C
{
public:
    // Common code...

    template <typename U = T, std::enable_if_t<std::is_same<bool, U>::value, bool> = false>
    void only_for_bool() {/*..*/}
};

C++20 将允许更好的语法:

template <typename T>
class C
{
public:
    // Common code...

    void only_for_bool() requires (std::is_same<bool, T>::value) {/*..*/}
};

【讨论】:

  • 我有一个问题:template &lt;typename U = T, std::enable_if_t&lt;std::is_same&lt;bool, U&gt;::value, bool&gt; = false&gt; 是否不等于:template&lt;typename = std::enable_if_t&lt;std::is_same&lt;bool,T&gt;::value&gt;&gt;?为什么需要做typename U = T 和最后一个= false 位?
  • 对于 SFINAE,方法应该是模板。 class 是不够的,所以你会遇到硬错误而不是 Ssubstitution Failure.
  • typename = std::enable_if_t&lt;cond&gt; 可以被劫持only_for_bool&lt;int, void&gt;,不允许其他具有互补条件的重载(如果您想要intbool 的不同版本)(因为默认模板不是签名的一部分)。 std::enable_if_t&lt;cond, bool&gt; = false 允许互补条件,不能被劫持(条件还应该检查提供的代码中的 T == U)。
猜你喜欢
  • 2020-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多