c++ - 关于运算符重载和参数相关查找,Visual Studio 10 和 GCC 4.5 之间的哪个编译器是正确的?

标签 c++ visual-studio-2010 gcc operator-overloading argument-dependent-lookup

我有以下代码:

class Foo;
class Bar;

class Bar {
public:
    Bar() {
    }

    Bar(Foo &foo) {
    }
};

class Foo {
public:
    Foo() {
    }
    Foo(Foo &foo) {
    }
    Foo(const Bar &bar) {
    }
};

Bar operator >> (const Bar &left, const Bar &right) { return Bar(); }

Foo a;
Foo b;
Foo c = a >> b;

在 Visual Studio 10 中,上述代码可以正常编译:编译器识别出 Bar 可以从 Foo& 实例化,因此它会调用适当的运算符 >>,然后返回一个 Bar 实例,并适本地调用构造函数 Foo(const Bar &)

但是,GCC 4.5 不编译上述代码。它输出以下错误:

error: no matching function for call to 'Foo::Foo(Foo)'
note: candidates are: Foo::Foo(const Bar&)
note:                 Foo::Foo(Foo&)
note:                 Foo::Foo()

为什么会发生上述情况,根据语言标准,哪个编译器是正确的?

编辑:

为什么 C++ 由于 c = a >> b 而创建临时 Foo 对象,因为 Foo(const Bar &)存在吗?

最佳答案

这与重载或参数查找无关。通过定义 Foo(Foo&),您已禁用默认复制构造函数 Foo(const Foo&) 的生成,该构造函数是初始化 c 所必需的> 来自右值。添加带有 Foo(const Foo&) 签名的 ctor,您的代码将运行良好。我不知道为什么 VS10 会编译这个,但我会尝试查找指定为什么它不应该发生的子句。

我们开始: §12.8(1) 指定类 X 的非模板构造函数是复制构造函数,如果其第一个参数的类型为 X&、const X&、 volatile X& 或 const volatile X& 并且没有其他参数或所有其他参数都有默认值。

§12.8(5) 说,如果我们没有为 X 定义复制构造函数(以上述任何形式),编译器将以 X(const X&) 的形式定义复制构造函数。

因此定义 Foo(Foo&) 定义了一个复制构造函数,因此编译器不能再隐式定义 Foo(const Foo&)。

关于c++ - 关于运算符重载和参数相关查找,Visual Studio 10 和 GCC 4.5 之间的哪个编译器是正确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6358073/

相关文章:

python - 如何卸载 IronPython 工具?

c - gcc 优化涉及常量位运算的代码

c++ - 在 visual studio 和 eclipse 中打印 wchar_t 会给出不同的结果

c - 显示 C 文件中的所有函数

c++ - 在 OpenGL/GLFW 中管理默认着色器

c++ - 错误LNK2019,如何解决? *更新*

gcc - 在 OS X 10.9 Mavericks 上编译 Mesos 时如何修复 "implicit instantiation"错误?

c - 进程调用 ptrace(PTRACE_TRACEME, ...) 后会发生什么?

c++ - 从 LUA 脚本调用 C++ 类函数

c++ - Lambda:是从 lambda 未定义行为中的函数范围捕获 const char *