【发布时间】:2020-12-08 16:21:54
【问题描述】:
我编写了以下类,它存储固定值 (constant) 或获取值的函数 (get)。
template <typename T>
class DynamicValue {
private:
bool isConstant;
union {
T constant;
std::function<T()> get;
};
void copy(const DynamicValue& value) {
isConstant = value.isConstant;
if (isConstant) {
constant = value.constant;
} else {
std::cout << "won't overcome next line" << std::endl;
get = value.get;
std::cout << "why!" << std::endl;
}
}
public:
DynamicValue(const T& constant) : isConstant(true), constant(constant){};
template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
DynamicValue(F&& get) : isConstant(false), get(std::forward<F>(get)) {}
DynamicValue(const T* pointer) : DynamicValue([pointer]() { return *pointer; }) {}
DynamicValue(const DynamicValue& value) { copy(value); }
~DynamicValue() {}
DynamicValue& operator=(const DynamicValue& value) {
copy(value);
return *this;
}
operator T() { return isConstant ? constant : get(); }
};
我还编写了以下虚拟类来展示我遇到的问题:
class Object {
private:
DynamicValue<int> num;
public:
Object(DynamicValue<int> num) : num(num) {}
};
问题是当我尝试使用函数初始化Object 时(例如,通过执行Object b([] { return 1; });)程序崩溃。我已将崩溃范围缩小到复制功能内的get = value.get; 行。我还注意到,如果我将get 移出工会,则不会再发生崩溃。
您可以尝试一个现场示例here。
为什么会发生这种情况,我该如何解决(将get 保留在联合中)?
【问题讨论】:
-
具有构造函数的对象的联合总是很棘手。您必须显式构造此类对象。
-
fwiw,
std::variant是“新联盟”。 -
@Someprogrammerdude 显式构造是什么意思?
-
他的意思是接收成员
get没有正确构建。将行更改为auto get = value.get将避免崩溃。 -
@Thomas 是的,但它实际上也不会实现任何目标
标签: c++ copy-constructor unions std-function