非模板 class,以模板 class 作为字段,未指定模板参数

Non-template class with a template class as a field without specifying template parameters

有没有办法得到像这样的模板class

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

并有另一个 class 可以接受 A<true>A<false> 作为参数或字段,而不是模板 class 本身。像这样:

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);
};

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

Or is this simply impossible because two objects of the same class with different template arguments are treated as different types by the compiler?

class模板A的两个不同特化A<true>A<false>确实是不同的类型。

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

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

或者您可以利用从公共基础 class:

派生的 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
}

如@Jarod42 在评论中提到的另一种选择是使用std::variant,前提是您使用的是 C++17(或更高版本);特别是 std::variant<A<true>, A<false>>.