正如标题所说,
一个典型的答案是:
允许任何和所有代码转换不会改变程序的可观察行为的规则
我们会不时地从某些实现中获取行为,这些行为归因于此规则.好多次错了.那么,这个规则究竟是什么呢.标准没有明确地将此规则作为一个部分或段落提及,那么究竟什么属于这条规则的范围?对我来说,这似乎是一个灰色区域,标准没有详细定义.有人可以根据标准的参考资料详细说明细节.
注意:将其标记为C和C++,因为它与两种语言都相关.
在C++ 17中,std::optional
如果T
在[optional.object.dtor]中可以轻易破坏,那么新的强制要求它是可以轻易破坏的:
~optional();
1 效果:如果is_trivially_destructible_v<T> != true
并*this
包含值,则调用val->T::~T()
.
2 备注:如果is_trivially_destructible_v<T> == true
那么这个析构函数应该是一个简单的析构函数.
所以这个潜在的实现片段将不符合标准:
template <class T>
struct wrong_optional {
union { T value; };
bool on;
~wrong_optional() { if (on) { value.~T(); } }
};
Run Code Online (Sandbox Code Playgroud)
我的问题是:这项任务的优势是什么?据推测,对于简单的可破坏类型,编译器可以发现这value.~T()
是一个无操作并且不会发出代码wrong_optional<T>::~wrong_optional()
.
当我开始利用C++ 17结构化绑定和if运算符init语句以获得更优雅的函数结果报告和检查时,如果符合C++ Core Guideline F21,我开始执行以下操作:
std::pair<bool, int>Foo()
{
return {true, 42}; //true means that function complete with no error and that 42 is a good value
}
void main(void)
{
if (auto [Result, Value] = Foo(); Result)
{
//Do something with the return value here
}
}
Run Code Online (Sandbox Code Playgroud)
然后,当然,我觉得为这样的返回类型设置一个可重用的模板会很好,所以没有人必须复制该对的bool部分:
template <typename T> using validated = std::pair<bool,T>;
validated<int> Foo()
{
return {true, 42};
}
void main(void)
{
if (auto [Result, Value] = Foo(); Result)
{
//Do something with the return value here …
Run Code Online (Sandbox Code Playgroud)