【发布时间】:2021-10-01 00:00:15
【问题描述】:
我正在编写一个模板类来管理 2 个类的联合。除了Get() 函数之外,所有函数都非常简单。它看起来像这样:
UnionPair.hpp
template <class First, class Second>
class UnionPair {
public:
UnionPair() : state_(State::kEmpty){};
~UnionPair(){};
void Reset();
void Set(std::unique_ptr<First>&& first);
void Set(std::unique_ptr<Second>&& second);
template <First>
First *Get();
template <Second>
Second *Get();
private:
enum class State { kEmpty, kFirst, kSecond } state_;
union {
std::unique_ptr<First> first_;
std::unique_ptr<Second> second_;
};
};
UnionPair.cpp
template <class First, class Second>
template <First>
First *UnionPair<First, Second>::Get() {
return first_.get();
}
template <class First, class Second>
template <Second>
Second *UnionPair<First, Second>::Get() {
return second_.get();
}
我正在尝试使 Get() 函数模板方法只能使用其实例化的 UnionPair 对象的模板类调用,以便它们可以被调用它们的模板类重载。以上代码无法编译。
我对如何调用它的想法是这样的,但是当我尝试调用它们时出现编译器错误:
// Definitions of structs A, B and C here
UnionPair<A, B> pair;
pair.Set(std::unique_ptr(new A()));
pair.Get<A>(); // should return a pointer to A (causes a compiler error right now)
pair.Get<C>(); // should cause a compiler error
我不确定如何在 .cpp 文件中实现此方法,或者是否可行。我一直在阅读有关模板内的专业化的文章,但没有看到任何与我的类似的示例,或者专业化类必须与对象的模板类相同的示例。
我的用法/定义有什么问题?我正在尝试做的事情可能吗?如果没有,有没有其他选择?我不想做的是像First *GetFirst() 这样为 First 和 Second 分别设置一个 getter,因为这依赖于对象实例化中类的顺序并且不清楚。
旁注:如果有一个 c++ 库来管理工会成员的状态、设置和获取,我会考虑使用它,但我仍然想弄清楚我的问题。
【问题讨论】:
-
处理这个问题的 C++ 标准库类模板是std::variant
-
有趣。看起来这就是我要找的东西,但我认为如果您尝试从中获取错误的类型,它会引发运行时错误?这是否意味着没有办法得到编译器错误?我也不能在我的项目中使用 c++ 17,所以我不能使用这个类。但是感谢您指出!
-
像这样将模板代码放入
.cpp文件是行不通的。您犯了一个非常常见的错误,即预先编写大量代码,然后才试图使一切正常。专业的 C++ 开发人员不会那样工作。他们只写了几行代码,编译,测试,确保它们工作,然后再写几行。你应该从一个只有几行代码的模板开始,让所有这些工作,然后再写几行模板代码。 -
我真的不明白我写的这 30 行代码是如何“大堆”的......
-
我不认为当使用错误的 A 或 B 之一时您将能够得到编译器错误,因为编译器可能不知道在构造对象后设置了哪个,但是使用 C 时会出现编译器错误 —
get<C>(variant<A,B>)应该是错误。