Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Clang不能与std::experimental::optional一起正常工作_C++_Macos_Clang_C++14_Optional - Fatal编程技术网

C++ Clang不能与std::experimental::optional一起正常工作

C++ Clang不能与std::experimental::optional一起正常工作,c++,macos,clang,c++14,optional,C++,Macos,Clang,C++14,Optional,似乎clang不能与std::experimental::optional一起正常工作 考虑下面的例子: #include <experimental/optional> #include <iostream> struct Foo { int bar; }; int main() { Foo foo; std::experimental::optional<Foo> opt = foo; opt.value().bar = 42;

似乎clang不能与
std::experimental::optional
一起正常工作
考虑下面的例子:

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

struct Foo { int bar; };

int main() {
    Foo foo;
    std::experimental::optional<Foo> opt = foo;
    opt.value().bar = 42;
    std::cout << opt.value().bar << std::endl;
}
我没能在bug报告中找到任何关于clang的问题。
谁的行为举止得体?我猜g++工作得很好,而clang似乎被窃听了。我错了吗?

EDIT1

实际上,这个错误似乎是由于
坏的\u可选的\u访问的定义造成的,即使这个问题是在使用clang时发生的

EDIT2

没有命令行参数,但
-std=c++14

在osx上使用clang执行的测试,只要不使用
value
member方法,它就可以很好地编译(因此
optional
免费提供)。
这意味着它使用以下方式编译和链接:

opt->bar
而不是:

opt.value().bar

您的代码看起来非常好,
opt.value()
应该返回对所包含的值的引用,假设它已启用或引发异常。我们可以看看其中一个例子比后面的例子多,它包括以下段落:

对分离对象使用间接运算符是一种未定义的行为。此行为提供了最大的运行时性能。除了间接运算符,我们还提供成员函数值,如果存在引用,则返回对包含值的引用,否则抛出异常(源自逻辑错误)

如果看一下,它将
value()
描述为:

在您的情况下,
opt
处于激活状态,如果不是,它应该抛出,我们不会调用未定义的行为

注意,这是在最近几个版本的clang on Wandbox()上编译的

因此,正如Petesh所建议的,这可能是在您的平台上故意的,但确认这一点的唯一方法是提交错误报告


另请注意,正如提案中所述,还有一种可能是短期选择。

TL;医生:

@Petesh在评论中的解决方案为我解决了这个问题(发生在从OSX上的源代码构建的Clang 4.0.0中),即在…/实验/可选中添加默认实现(
=default
):
std::实验::坏的可选访问::~坏的可选访问‌​()u NOEXCEPT=默认值

详细信息:

根据@Shafik的答案使用解引用运算符并没有按预期工作,因为当前实现在解引用未连接的可选项时提供
(void)0
作为值。例如,这会产生一个可选的0,这是不正确的行为。(我也不认为(dis)接合检查应该作为断言来实现,因为断言很可能在发布版本中编译出来,这是出乎意料的。)

要解决
(void)0
问题,必须使用正确的行为定义
\u LIBCPP\u ASSERT
——如果
\u LIBCPP\u DEBUG\u LEVEL
被定义为至少1,那么
\u LIBCPP\u ASSERT
将被定义为
((x)?(void)0:(\u VSTD::fprintf(stderr,“%s\n”,m),\u VSTD::abort())
,,这将产生预期的行为


但问题是,根据
\u LIBCPP\u DEBUG\u级别
的说法,这是一项正在进行的工作,定义它将产生“相当严重的编译错误”。嗯,我试过了,他们没有撒谎(

您使用的是哪种
可选
实现?是它还是版本?@nicolas libstdc++with g++,libc++with clang.对我来说很好(linux,clang 3.5或3.7,libc++3.5)。您忘了显示命令行。快速浏览标题会告诉我们为什么会出现链接问题-
bad\u可选\u如果您调用
value()
类中有一个虚拟析构函数,这意味着除了vtable之外,还需要实现。在
/usr/lib/libc++.dylib
中没有导出的
实验性的
符号。我同意苹果公司的决定,不将
实验性的
代码放入它们的代码中在操作系统libc++上,因为这将构成一份合同,出于ABI的原因继续提供它。根据libc++源代码,看起来至少有人会努力从库中删除符号,对我来说,这听起来像是一个积极的决定,但如果你觉得这是一个bug,那么你可以总是向苹果公司提交雷达文件。如果你想解决这个问题,你可以随时输入
std::experimental::bad_optional_access::~bad_optional_access()_NOEXCEPT=default;
我喜欢github。比github好得多。@T.C.githug确实很可爱!!:-DHonestly,我不明白你的意图。禁止使用
可选的
是有道理的。如果不是
成员方法,让客户端使用整个类有意义吗?听起来像个bug。我有没有想过错过了什么?不管怎样,投了赞成票。:-@skypjack我看不出Petesh的推理有明显的缺陷。至于为什么,我不知道。我会假设这是一个bug,提交一个bug报告,看看响应是什么。不,bug报告应该提交给macosx。
opt.value().bar
constexpr T const& optional<T>::value() const;
T& optional<T>::value();
constexpr T const& value()
{
    return *this ? storage_.value_ : (throw bad_optional_access(""), storage_.value_);
}