gpt4 book ai didi

C++ 运算符查找规则/Koenig 查找

转载 作者:IT老高 更新时间:2023-10-28 23:00:31 29 4
gpt4 key购买 nike

在编写测试套件时,我需要提供 operator<<(std::ostream&... 的实现供 Boost 单元测试使用。

这行得通:

namespace theseus { namespace core {
std::ostream& operator<<(std::ostream& ss, const PixelRGB& p) {
return (ss << "PixelRGB(" << (int)p.r << "," << (int)p.g << "," << (int)p.b << ")");
}
}}

这不是:

std::ostream& operator<<(std::ostream& ss, const theseus::core::PixelRGB& p) {
return (ss << "PixelRGB(" << (int)p.r << "," << (int)p.g << "," << (int)p.b << ")");
}

显然,当 g++ 尝试解决运算符的使用时,第二个未包含在候选匹配中。为什么(是什么规则造成的)?

调用 operator<< 的代码深入 Boost 单元测试框架,但这里是测试代码:

BOOST_AUTO_TEST_SUITE(core_image)

BOOST_AUTO_TEST_CASE(test_output) {
using namespace theseus::core;
BOOST_TEST_MESSAGE(PixelRGB(5,5,5)); // only compiles with operator<< definition inside theseus::core
std::cout << PixelRGB(5,5,5) << "\n"; // works with either definition
BOOST_CHECK(true); // prevent no-assertion error
}

BOOST_AUTO_TEST_SUITE_END()

作为引用,我使用的是 g++ 4.4(尽管目前我假设这种行为符合标准)。

最佳答案

在参数相关查找(koenig 查找的正确名称)中,编译器将在每个参数的命名空间中声明的函数添加到重载函数集。

在您的情况下,第一个 operator<<在命名空间 thesus::core, 中声明这是您调用运算符的参数的类型。因此这个 operator<<被考虑用于 ADL,因为它是在关联的命名空间中声明的

在第二种情况下,operator<<似乎在不是关联命名空间的全局命名空间中声明,因为参数 1 的类型来自命名空间 std并且参数 2 的类型来自命名空间 theseus::core .

实际上,可能是您的第二个 operator<<没有在全局命名空间中声明,因为可以通过查看父范围来找到它。也许你有更多类似的东西?如果您可以发布更多代码,我们可以给出更好的答案。


好的,我记得,当 ADL 在当前作用域中找到名称时,它不会在父作用域中查找。所以 boost 宏 BOOST_TEST_MESSAGE扩展为包含 operator<<并且在范围树中有一些不可行的operator<<在表达式和全局范围之间。我更新了代码来说明这一点(希望如此)。

#include <iostream>

namespace NS1
{
class A
{};

// this is found by expr in NS2 because of ADL
std::ostream & operator<<(std::ostream &, NS1::A &);
}


// this is not seen because lookup for the expression in NS2::foo stops when it finds the operator<< in NS2
std::ostream & operator<<(std::ostream &, NS1::A &);

namespace NS2
{
class B
{};

// if you comment this out lookup will look in the parent scope
std::ostream & operator<<(std::ostream &, B &);

void foo(NS1::A &a)
{
std::cout << a;
}
}

关于C++ 运算符查找规则/Koenig 查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4603886/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com