Naprawdę dziwne i nieoczekiwane zachowanie klangu 5 zostało wykryte po przejściu na C++ 17 i zastąpieniu niestandardowego rozwiązania std::optional
standardowym. Z jakiegoś powodu, emplace()
został wyłączony z powodu błędnej oceny cechy std::is_constructible
klasy parametrów.clang 5: std :: opcjonalne wkręty do instancji std :: is_constructible cecha parametru typ
pewnych specyficznych warunków musi być spełniony przed reprodukuje:
#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);
}
};
żywo przykład na godbolt.org
Zmiana któregokolwiek z warunków i kompiluje, jak oczekiwano. Czy istnieje jakaś nieznana niespójność w standardzie, która sprawia, że klang odrzuca ten kod, będąc jednocześnie zgodny?
marginesie: GCC 7,1 i GCC 7,2 nie ma problemu z powyższym kodu.
raport Bug w: bugs.llvm.org
Może to być błąd kompilatora. –
@CrisLuengo, mam nadzieję, że jest łatwiejsze do naprawienia niż standardowe. – GreenScape
W gruncie rzeczy naprawdę jest to pytanie dotyczące prawnika językowego. Na to należy odpowiedzieć. – StoryTeller