C ++ 17 — Как я могу использовать std :: необязательный в C ++?

Я пытаюсь использовать std :: необязательный, но мой код вызывает ошибку.
Я указал #include <experimental/optional> и параметры компилятора -std=c++1z, -lc++experimental,

Как пользоваться std::experimental::optional?

Ниже приведен код:

#include <experimental/optional>
#include <iostream>

std::experimental::optional<int> my_div(int x, int y) {
if (y != 0) {
int b = x / y;
return {b};
}
else {
return {};
}
}

int main() {
auto res = my_div(6, 2);
if (res) {
int p = res.value();
std::cout << p << std::endl;
}
}

сообщение об ошибке:

optional.cpp:17:21: error: call to unavailable member function 'value':
int p = res.value();
~~~~^~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/experimental/optional:525:17: note: candidate function has been explicitly made unavailable
value_type& value()
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/experimental/optional:517:33: note: candidate function has been explicitly made unavailable
constexpr value_type const& value() const
^
1 error generated.

ОС: macOS 10.12.5

Версия компилятора:

Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

8

Решение

Хорошо, после того, как вы опубликуете свою ошибку, я могу разобраться в этом (но вы могли бы сделать точно то же самое).

КОРОЧЕ

Это проблема / ошибка с optional как предусмотрено Apple на OSX, но есть простой обходной путь.

В ЧЕМ ДЕЛО

Файл /Library/Developer/CommandLineTools/usr/include/c++/v1/exper‌​imental/optional объявляет нарушающую функцию optional::value как

template <class _Tp>
class optional
: private __optional_storage<_Tp>
{
/* ... */

_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
constexpr value_type const& value() const
{
if (!this->__engaged_)
throw bad_optional_access();
return this->__val_;
}

_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
value_type& value()
{
if (!this->__engaged_)
throw bad_optional_access();
return this->__val_;
}
/* ... */
};

Запуск только препроцессора (опция компилятора -E) показывает, что макросы расширяются до

#define _LIBCPP_INLINE_VISIBILITY \
__attribute__ ((__visibility__("hidden"), __always_inline__))
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
__attribute__((unavailable))

В частности, макрос _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS является #defineг в файле /Library/Developer/CommandLineTools/usr/include/c++/v1/__config как

// Define availability macros.
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
// ...
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
// ...
#else
// ...
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
// ...
#endif

Таким образом, это специфичное для Apple изменение от libc ++ API LLVM. Как следует из названия макроса, причина в том, что Apple не делает

class bad_optional_access
: public std::logic_error
{
public:
bad_optional_access() : std::logic_error("Bad optional Access") {}
virtual ~bad_optional_access() noexcept;
};

доступно и, следовательно, не может реализовать функциональность (optional::value) это зависит от этого. Зачем bad_optional_access не предусмотрено (тем самым нарушая стандарт) неясно, но это может быть связано с тем, что библиотека (dylib) должна быть изменена, чтобы содержать bad_optional_access::~bad_optional_access(),

КАК РАБОТАТЬ ВОКРУГ

просто используйте optional::operator* вместо

int p = *res;

Единственное отличие состоит в том, что проверка доступа не выполняется. Если вам это нужно, сделайте это сами

template<typename T>
T& get_value(std::experimental::optional<T> &opt)
{
if(!opt.has_value())
throw std::logic_error("bad optional access");
return *opt;
}

template<typename T>
T const& get_value(std::experimental::optional<T>const &opt)
{
if(!opt.has_value())
throw std::logic_error("bad optional access");
return *opt;
}
14

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]