Почему следующий метод не является constexpr?
constexpr std::optional<std::unique_ptr<int>> test2(void) {
return std::nullopt;
}
Clang выдает мне следующую ошибку:
[build] /.../<>.cxx:223:47: error: constexpr function's return type 'std::optional<std::unique_ptr<int>>' is not a literal type
[build] 223 | constexpr std::optional<std::unique_ptr<int>> test2(void) {
[build] | ^
[build] /nix/store/fsb7lmhyy01flrnviwjfz3fgm53w990v-libcxx-18.1.7-dev/include/c++/v1/optional:582:7: note: 'optional<std::unique_ptr<int>>' is not literal because it has base class '__optional_move_assign_base<unique_ptr<int, default_delete<int>>>' of non-literal type
[build] 582 | : private __optional_move_assign_base<_Tp>,
Я использую Clang-версию: 18 и std=С++20.
Может ли кто-нибудь дать мне несколько советов?
Я настроил свою среду с помощью nix, поэтому ошибка должна быть воспроизводимой:
{ pkgs ? import <nixpkgs> {} }: pkgs.mkShell {
nativeBuildInputs = with pkgs.buildPackages; [
# system tools
zsh
git
openssl
# basic configuration
pkgs.llvmPackages_18.stdenv
pkgs.llvmPackages_18.libcxx
pkgs.llvmPackages_18.libcxxStdenv
pkgs.llvmPackages_18.bintools
pkgs.llvmPackages_18.clang-tools
cmake
# ...
];
}
Та же ошибка возникает при использовании класса или структуры вместо int.
@FrançoisAndrieux да, мне это тоже подходит. GCC тоже работает. Это ошибка в GCC, clang или на моей стороне? Вы сможете воспроизвести ошибку, используя конфигурацию nix. Но спасибо за ваши усилия :)
@FrançoisAndrieux godbolt clang по умолчанию использует libstdc++, вопрос помечен тегом libc++, если вы добавите -stdlib=libc++
, то это не сработает.
Лучше MCVE: godbolt.org/z/E6szqoMKb
Воспроизведено с использованием правильной стандартной библиотеки: godbolt.org/z/4eThzGEhY
Кстати, этот код подходит для C++23: godbolt.org/z/Pvxh8fvK6
@FrançoisAndrieux pointerpointer.com
Я предполагаю, что ваша реализация компилятора/стандартной библиотеки еще не реализовала отчет о дефектах, полученный из open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2231r1.html.
constexpr std::unique_ptr
— это функция библиотеки C++23 (P2273), поэтому вам необходимо использовать -std=c++23
, чтобы компилятор работал.
Я предполагаю, что OP не выполняет никаких действий, которые на самом деле могли бы привести к созданию std::unique_ptr
. Тогда возникает вопрос, зачем вообще нужна constexpr
-дружественная std::unqiue_ptr
. Компилятор утверждает, что std::optional<std::unique_ptr>
нельзя использовать в качестве возвращаемого типа, поскольку это не литеральный тип, но его деструктор constexpr
в C++20 находится после open-std.org/jtc1/sc22/wg21/docs/papers/ 2021/p2231r1.html, который, возможно, еще не реализован в версии OP Clang.
@ user17732522 MSVC-STL и libc++ уже реализовали документ, и для этого я зарегистрировал ошибку libstdc++.
@user17732522 user17732522 приведенный выше пример является минимальным рабочим (или в данном случае неудачным) примером, фактический код намного больше, я в основном задавался вопросом, почему код был принят MSVC и gcc, но не clang. Тем не менее спасибо за ваши усилия :)
«Может кто-нибудь дать мне несколько советов?» Указатели.