使用 clang 和 libstdc++ 时不能使用 experimental::optional 的常量引用
Cannot use a constant reference of experimental::optional when using clang & libstdc++
我正在使用 experimental::optional<> 变量的常量引用,但是当我使用 operator->() 在上面,我有一个编译错误,但只有在使用 clang++ and libstdc++.
时才会出现
#include <experimental/optional>
#include <iostream>
#include <vector>
int main(void)
{
std::experimental::optional<std::vector<int>> opt;
const auto &rf = opt;
opt.emplace();
opt->push_back(1);
std::cout << "opt->size() = " << opt->size()
<< " rf->size() = " << rf->size() << "\n";
return 0;
}
运行 这个程序:
$ clang++ -W -Wall -std=c++14 -stdlib=libc++ test.cc && ./a.out
opt->size() = 1 rf->size() = 1 # OK
$ g++ -W -Wall -std=c++14 test.cc && ./a.out
opt->size() = 1 rf->size() = 1 # OK
$ clang++ -W -Wall -std=c++14 test.cc
In file included from test.cc:1:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:576:16: error: call to '__constexpr_addressof' is ambiguous
{ return __constexpr_addressof(this->_M_get()); }
^~~~~~~~~~~~~~~~~~~~~
test.cc:14:40: note: in instantiation of member function 'std::experimental::fundamentals_v1::optional<std::vector<int, std::allocator<int> > >::operator->' requested here
<< " rf->size() = " << rf->size() << "\n";
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:173:20: note: candidate function [with _Tp = const std::vector<int, std::allocator<int> >, = <>]
constexpr _Tp* __constexpr_addressof(_Tp& __t)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:180:17: note: candidate function [with _Tp = const std::vector<int, std::allocator<int> >, = <>]
inline _Tp* __constexpr_addressof(_Tp& __t)
^
1 error generated.
每当我使用常量引用时就会出现此错误:显然非常量引用是可以的。
我将 Linux Mint 18 与这些版本的 g++/libstdc++ 5.4.0 和 clang++ 3.8.0 一起使用:
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ dpkg-query -s libstdc++-5-dev
...
Version: 5.4.0-6ubuntu1~16.04.4
...
$ clang++ --version
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
这是我的程序、libstdc++ 或 clang++ 中的错误吗?
更新:随着 clang 3.9.0 问题消失了。 (正如 Richard Smith 和 Ville Voutilainen 在下面解释的那样,libstdc++ 似乎期望编译器以某种与 clang 3.8.0 不匹配的方式运行。)
在我看来,这确实像是一个 clang 错误,因为它诊断为不明确的重载具有互斥的 enable_if 约束,因此它们不应该是不明确的。
我正在使用 experimental::optional<> 变量的常量引用,但是当我使用 operator->() 在上面,我有一个编译错误,但只有在使用 clang++ and libstdc++.
时才会出现#include <experimental/optional>
#include <iostream>
#include <vector>
int main(void)
{
std::experimental::optional<std::vector<int>> opt;
const auto &rf = opt;
opt.emplace();
opt->push_back(1);
std::cout << "opt->size() = " << opt->size()
<< " rf->size() = " << rf->size() << "\n";
return 0;
}
运行 这个程序:
$ clang++ -W -Wall -std=c++14 -stdlib=libc++ test.cc && ./a.out
opt->size() = 1 rf->size() = 1 # OK
$ g++ -W -Wall -std=c++14 test.cc && ./a.out
opt->size() = 1 rf->size() = 1 # OK
$ clang++ -W -Wall -std=c++14 test.cc
In file included from test.cc:1:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:576:16: error: call to '__constexpr_addressof' is ambiguous
{ return __constexpr_addressof(this->_M_get()); }
^~~~~~~~~~~~~~~~~~~~~
test.cc:14:40: note: in instantiation of member function 'std::experimental::fundamentals_v1::optional<std::vector<int, std::allocator<int> > >::operator->' requested here
<< " rf->size() = " << rf->size() << "\n";
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:173:20: note: candidate function [with _Tp = const std::vector<int, std::allocator<int> >, = <>]
constexpr _Tp* __constexpr_addressof(_Tp& __t)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/experimental/optional:180:17: note: candidate function [with _Tp = const std::vector<int, std::allocator<int> >, = <>]
inline _Tp* __constexpr_addressof(_Tp& __t)
^
1 error generated.
每当我使用常量引用时就会出现此错误:显然非常量引用是可以的。
我将 Linux Mint 18 与这些版本的 g++/libstdc++ 5.4.0 和 clang++ 3.8.0 一起使用:
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ dpkg-query -s libstdc++-5-dev
...
Version: 5.4.0-6ubuntu1~16.04.4
...
$ clang++ --version
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
这是我的程序、libstdc++ 或 clang++ 中的错误吗?
更新:随着 clang 3.9.0 问题消失了。 (正如 Richard Smith 和 Ville Voutilainen 在下面解释的那样,libstdc++ 似乎期望编译器以某种与 clang 3.8.0 不匹配的方式运行。)
在我看来,这确实像是一个 clang 错误,因为它诊断为不明确的重载具有互斥的 enable_if 约束,因此它们不应该是不明确的。