【发布时间】:2015-04-01 01:01:59
【问题描述】:
以下代码在 g++ 4.9.2 和 clang++ 3.7.0 下的行为不同。哪一个是正确的?标准中的哪些部分与此相关?谢谢。
#include <iostream>
using namespace std;
struct Base {
Base() = default;
Base(const Base&) = default;
Base(Base&&) = delete;
};
struct Derived : Base {
};
int main() {
const Base& b = true ? Derived() : Base();
}
g++ 接受它并且 clang++ 给出错误incompatible operand types ('Derived' and 'Base')。详情见下文。
[hidden]$ g++ -v
Using built-in specs.
COLLECT_GCC=/usr/bin/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.9.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --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-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.9.2 20150212 (Red Hat 4.9.2-6) (GCC)
[hidden]$ g++ -std=c++11 b.cpp
[hidden]$ clang++ -v
clang version 3.7.0 (http://llvm.org/git/clang.git 6bbdbba8ec8a7730c68fee94363547dc2dc65b10)
Target: x86_64-unknown-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/3.4.6
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.9.2
Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.9.2
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
[hidden]$ clang++ -std=c++11 b.cpp
b.cpp:14:24: error: incompatible operand types ('Derived' and 'Base')
const Base& b = true ? Derived() : Base();
^ ~~~~~~~~~ ~~~~~~
1 error generated.
【问题讨论】:
-
Clang 可能希望您使用显式转换
-
@dyp:克里斯没有说复制初始化意味着使用复制构造函数,这是错误的:如果有移动构造函数,则可能不需要复制构造函数。他说既然有拷贝构造函数,拷贝初始化应该成功,这是真的,要么有可用的移动构造函数,要么没有,拷贝构造函数被使用。
-
@BenVoigt,没关系,当它说复制初始化时,我真的没有足够注意。进一步看,应该归结为
Base b = Derived();的重载决议选择了哪个构造函数 -
@dyp,也许值得让 Clang 家伙知道这种情况下的异常错误消息?我承认这是相当做作的。
-
切向问题:有什么办法可以做 OP 试图做的事情吗? (即根据条件将引用直接绑定到
Base()或Derived(),并延长临时的生命周期?