当切换到 c++17 并用std::optional
标准解决方案替换自定义解决方案时,检测到 clang 5 的一个非常奇怪和意外的行为。由于某种原因,由于对参数类特征的emplace()
错误评估而被禁用。std::is_constructible
在复制之前必须满足一些特定的先决条件:
#include <optional>
/// Precondition #1: T must be a nested struct
struct Foo
{
struct Victim
{
/// Precondition #2: T must have an aggregate-initializer
/// for one of its members
std::size_t value{0};
};
/// Precondition #3: std::optional<T> must be instantiated in this scope
std::optional<Victim> victim;
bool foo()
{
std::optional<Victim> foo;
// An error
foo.emplace();
/// Assertion is failed
static_assert(std::is_constructible<Victim>::value);
}
};
godbolt.org上的实时示例
更改任何先决条件并按预期编译。标准中是否存在一些未知的不一致,使 clang 在合规的同时拒绝此代码?
附带说明:GCC 7.1和GCC 7.2对上述代码没有任何问题。
错误报告:bugs.llvm.org