C++重载函数名查找错误

标签 c++ operator-overloading name-lookup

我在 C++ 中遇到有关名称查找的奇怪错误。

可以使用以下最小示例重新创建错误:

#include <vector>
#include <iostream>

std::ostream& operator<<(std::ostream& out, const std::vector<int>& a) {
    for (size_t i = 0; i < a.size(); i++) {
        out << a[i] << std::endl;
    }
    return out;
}

namespace Test {

    struct A {
        // Label 1
        friend std::ostream& operator<<(std::ostream& out, const A&) {
            return out << "A" << std::endl;
        }
    };

    struct B {
        void printVector() noexcept {
            std::vector<int> v{1, 2, 3};
            std::cout << v << std::endl; // The error occurs in this line
        }
        // Label 2
        friend std::ostream& operator<<(std::ostream& out, const B&) {
            return out << "B" << std::endl;
        }
    };

}

int main() {
    Test::B().printVector();
}

编译这将导致以下错误消息:

cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'

您可以在这里自行测试:http://cpp.sh/5oya

奇怪的是,如果您分别删除标有 //Label 1//Label 2 的函数之一,代码编译并运行良好。

我现在的问题是:这是怎么回事?如何修复?

最佳答案

其他解决方法是在命名空间 std 中重载运算符 <<,而不是在全局命名空间中。(查找将在命名空间范围内找到它)

namespace std
{
    std::ostream& operator<<(std::ostream& out, const std::vector<int>& a) {
        for (size_t i = 0; i < a.size(); i++) {
            out << a[i] << std::endl;
        }
        return out;
    }
}

尝试 Here

[编辑]

另一种解决方法,对于不想污染全局命名空间或 std 的清教徒来说,是

...have the insertion operators in the same namespace as the class upon which it operates.

...讨论 here .

namespace Test
{
    std::ostream& operator<<(std::ostream& out, const std::vector<int>& a) {
        for (size_t i = 0; i < a.size(); i++) {
            out << a[i] << std::endl;
        }
        return out;
    }
}

工作代码 here .

关于C++重载函数名查找错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41621296/

相关文章:

c++ - 我在 visual studio 的调用堆栈上看到的这些十六进制字符串是什么

c++ - 加入 Portaudio 和 Opus

c++ - 为什么这个用两个参数声明的构造函数可以只用一个参数调用?

c++ - 在 C++ 中的模板化基类中查找名称

C++模板类继承

c++ - 对仅在断言中使用的变量使用 [[maybe_unused]] 是否有缺点?

c++ - 请求从非标量类型 "node*"转换为标量类型 "node"

c++ - 为 vector 删除删除了隐式赋值运算符?

c++ - 双向链表的输出

c++ - 稍后定义的重载函数的名称查找