Это не первый раз, когда я вижу, что какая-то конструкция принимается одними компиляторами и отвергается другими. Какой компилятор неправ, не всегда очевидно. Я предполагаю, что clang неправ, а gcc/msvc правы, но мне хотелось бы узнать мнение экспертов по C++, прежде чем сообщать об ошибке в llvm.
Исходный код:
#include
class A {
public:
class B {
public:
int i = 0;
B() = default;
};
std::optional b {};
A() {
b.emplace();
}
};
Ошибка компиляции:
$ clang -std=c++20 -o opt_clang.o -c opt.cpp
opt.cpp:14:11: error: no matching member function for call to 'emplace'
14 | b.emplace();
| ~~^~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/optional
1116 | emplace(_Args&&... __args)
| ^
/usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/optional
1128 | emplace(initializer_list __il, _Args&&... __args)
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Условия воспроизведения проблемы:
- Класс B должен быть вложен в A. Нет ошибки, если класс B находится за пределами A.
- Поле A::B::i должно существовать. При удалении поля ошибок не возникает.
- Конструктор B() должен иметь значение B() = default. Нет ошибок, если определено как B() {}.
- Конструктор B() не должен иметь параметров. Если есть один параметр, например. B(int), тогда принимается b.emplace(1).
$ clang --version
Ubuntu clang version 20.1.8 (0ubuntu4)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm-20/bin
Подробнее здесь: https://stackoverflow.com/questions/798 ... c-and-msvc
Мобильная версия