【问题标题】:Non-template class with a template class as a field without specifying template parameters以模板类为字段的非模板类,不指定模板参数
【发布时间】:2020-11-24 13:42:09
【问题描述】:

有没有办法拥有这样的模板类

template<bool state = true>
class A
{
};

并且有另一个类可以接受A&lt;true&gt;A&lt;false&gt; 作为参数或字段,而不是模板类本身。像这样:

class B
{
public:
    B(A& arg_a)
       : a(arg_a)
    {}

private:
    A& a;
};

int main()
{
    A<true> aTrue;
    A<false> aFalse;
    B bTrue(aTrue);
    B bFalse(aFalse);
};

或者这是否根本不可能,因为具有不同模板参数的同一类的两个对象被编译器视为不同的类型?关于如何设计它的其他建议也将不胜感激。我知道如果我只是将模板参数设为类字段,这种设计是可能的,但我想知道这是否可以使用模板参数来完成。

【问题讨论】:

  • 或者这根本不可能,因为具有不同模板参数的同一类的两个对象被编译器视为不同的类型?正确。
  • 拥有using typeA = A&lt;true&gt;;using typeB = A&lt;false&gt;; 可能会有所帮助,现在您可以考虑如何将typeAtypeB 传递给相同的方法。

标签: c++ templates member default-template-argument


【解决方案1】:

或者这根本不可能,因为具有不同模板参数的同一类的两个对象被编译器视为不同的类型?

类模板A的两个不同的特化A&lt;true&gt;A&lt;false&gt;确实是不同的类型。

您可以重载 B 的构造函数以允许它们中的每一个:

struct B {
    B(const A<true>&);
    B(const A<false>&);
}

或者您可以利用派生自公共基类的A 的任何特化来利用多态性:

#include <ios>
#include <iostream>

struct Base {
    virtual bool getState() const = 0;
};

template<bool state = true>
struct A : public Base {
    bool getState() const override { return state; }
};

struct B {
    bool state;
    B(const Base& base) : state(base.getState()) {}
};

int main() {
    A<true> a1{};
    A<false> a2{};
    std::cout << std::boolalpha 
        << B(a1).state << " "  // true
        << B(a2).state;        // false
}

另一个替代方法,正如 cmets 中 @Jarod42 所提到的,是使用 std::variant,前提是您使用的是 C++17(或更高版本);特别是std::variant&lt;A&lt;true&gt;, A&lt;false&gt;&gt;

【讨论】:

  • std::variant&lt;A&lt;false&gt;, A&lt;true&gt;&gt; 是另一种选择。
  • @Jarod42 是的,这是一个很好的选择,谢谢。相应地更新了答案。
  • 谢谢两位!太有见地了
猜你喜欢
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多