我有一个类似于以下内容的段落。
理论上,它应该能够工作。但是由于编译器(vs2015)并没有严格遵循标准,因此
因此,我的问题是如何使这段代码按预期工作?
完整的代码如下:
struct derive : base{
derive(unique_ptr ptr): base{func(ptr->some_data), std::move(ptr)}{}
};
理论上,它应该能够工作。但是由于编译器(vs2015)并没有严格遵循标准,因此
func(ptr->some_data), std::move(ptr)
的顺序是未定义的,即ptr
可能在被访问之前就被移动了。因此,我的问题是如何使这段代码按预期工作?
完整的代码如下:
#include <memory>
struct base {
virtual ~base() = 0 {}
protected:
base(std::unique_ptr<base> new_state) :
previous_state{ std::move(new_state) } {}
private:
std::unique_ptr<base> previous_state;
};
struct derive_base : base {
int get_a() const noexcept {
return a;
}
protected:
derive_base(int const new_a, std::unique_ptr<base> new_state) :
base{ std::move(new_state) }, a{ new_a } {}
private:
int a;
};
struct final_state : derive_base {
final_state(std::unique_ptr<base> new_state) :
derive_base{ dynamic_cast<derive_base&>(*new_state).get_a(), std::move(new_state) } {}
};
base::base()
的实现,除非编译器出现非常严重的错误(比Visual C++通常的不兼容性更糟糕),否则完全安全。 - Ben Voigtbase
构造函数是base(result_of_func_type, unique_ptr)
而不是base(result_of_func_type, unique_ptr&&)
。 如果VS在评估顺序上不符合标准,则前者不安全,但后者是安全的。 - Praetorian