在尝试使用基于lambda的“常量块”回答this question时,我遇到了clang++
和g++
对代码有效性不一致的情况。
#include <iostream>
#include <type_traits>
struct noncopyable
{
int a;
const noncopyable& operator=(noncopyable&&) = delete;
noncopyable(noncopyable&&) = delete;
const noncopyable& operator=(const noncopyable&) = delete;
noncopyable(const noncopyable&) = delete;
~noncopyable() = default;
};
void modify(noncopyable& a)
{
a.a = 0;
}
int main()
{
noncopyable a = { 25 }, b = { 42 };
[&, &a = static_cast<const noncopyable&>(a)]{
modify(b);
//modify(a); // uncommenting this should fail the build
}();
std::cout << a.a << " " << b.a << "\n";
// expected output 25 0
}
clang++
接受代码,并显示预期的输出,而g++
失败,并显示以下错误消息:
a.cpp: In function ‘int main()’:
a.cpp:22:5: error: binding ‘const noncopyable’ to reference of type ‘noncopyable&’ discards qualifiers
[&, &a = static_cast<const noncopyable&>(a)]{
^
clang++ -v
是
clang version 3.7.0 (tags/RELEASE_370/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/5.1.1
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/5.1.1
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
和g++ -v
是
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/5.1.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --disable-libgcj --with-isl --enable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 5.1.1 20150618 (Red Hat 5.1.1-4) (GCC)
用于编译代码的选项是:
-std=c++14 -Wall -Wextra -pedantic
哪个编译器是对的? g++
或clang++
? (或者,第三种选择,是因为另一个原因而无效的代码?)