【发布时间】:2021-01-21 16:26:59
【问题描述】:
我编写了以下类来创建任何类型的值,这些值在每次使用调用运算符时都是固定的或重新计算的:
template <typename T>
class DynamicValue {
private:
std::variant<T, std::function<T()>> getter;
public:
DynamicValue(const T& constant) : getter(constant){};
template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
DynamicValue(F&& function) : getter(function) {}
DynamicValue(const T* pointer) : DynamicValue([pointer]() { return *pointer; }) {}
DynamicValue(const DynamicValue& value) : getter(value.getter) {}
DynamicValue(DynamicValue& value) : DynamicValue((const DynamicValue&) value) {}
~DynamicValue() {}
T operator()() const { return getter.index() == 0 ? std::get<T>(getter) : std::get<std::function<T()>>(getter)(); }
};
我还写了这个函数,它接受一个DynamicValue<int> 并返回另一个DynamicValue<int>,它返回它的值加1:
DynamicValue<int> plus1(DynamicValue<int> a) {
return [a] { return a() + 1; };
}
但是,当我尝试使用它时,程序崩溃了:
DynamicValue<int> a = 1;
DynamicValue<int> b = plus1(a);
您可以尝试一个现场示例here。
经过一些测试,我认为问题在于复制构造函数,它被无休止地调用,但我不知道如何解决它。如何避免这种行为?
【问题讨论】:
-
您的意思是写
DynamicValue<int> plus1(DynamicValue<int>& a) {?我们能否将这个问题作为由错字引起的而结束? -
DynamicValue(DynamicValue& value)你不需要这个重载。惯用的 const 就足够了。实际上,您不需要任何复制 ctor。遵循零规则。 -
@πάνταῥεῖ 我不是故意写这个的,我试过了也没什么区别。
-
@bolov 我添加了这个重载作为我遇到的另一个错误的临时修复。无论哪种方式,在这种情况下,删除复制 ctor 都没有任何区别。
-
“在这种情况下删除复制 ctor 没有任何影响。” -- 请继续沿着这条路走下去。删除所有不需要重现错误的代码,c.f. minimal reproducible example.
标签: c++ lambda copy-constructor