gpt4 book ai didi

c++ - 依赖于参数的查找在从另一个 namespace 别名的类型上出现意外行为

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:02 24 4
gpt4 key购买 nike

我刚刚遇到了一些与参数相关的查找的有趣行为,我并不完全理解:

#include <iostream>

namespace a {
struct Foo {
Foo(int v1, int v2) : v1(v1), v2(v2) { }
int v1,v2;
};
}

namespace b {
template <typename T>
struct Baz : T {
using T::T;
};
}

namespace c {
using Foo = ::b::Baz< ::a::Foo>;

// (1) NOT FOUND BY ADL
// std::ostream& operator << (std::ostream& os, const Foo& foo)
// {
// return os << foo.v1 << "," << foo.v2;
// }
}

namespace b {

// (2) FOUND BY ADL
std::ostream& operator << (std::ostream& os, const ::c::Foo& foo)
{
return os << foo.v1 << "," << foo.v2;
}

}

int main()
{
c::Foo foo(1,2);
// Variant (1): ADL fails: should it not find
// c::operator<<(std::ostream&, const Foo&) ?
// Variant (2) compiles
std::cout << "foo: " << foo << std::endl;
}

我明白了 c::Foo实际上是 b::Baz<...> ,所以当我在 namespace b 中定义它时,ADL 找到运算符有点有意义.但这似乎违背了在 namespace c 中定义运算符的直觉。不起作用,因为 c::Foo 应该(恕我直言)允许编译器在 namespace c 中执行 ADL

为什么不是这样?这背后的原理是什么?

最佳答案

[basic.lookup.argdep]/2 :

Typedef names and using-declarations used to specify the types do not contribute to this set.

typedef 名称和 using 声明都不隶属于它们指定的类型。如果它们是(这实际上是违反直觉的,IMO),事情就会很容易崩溃;仅仅因为我对一些类进行了类型定义,所有调用现在都在考虑在类型定义附近添加的函数,这实际上是不希望的:

#include <string>

namespace A {
using str = std::string;
int stoi(str); // This will be a candidate in e.g. stoi(std::string{"0.4"}),
// leading to potentially different behavior or ambiguity

namespace B {
int stoi(std::string); // This is no candidate, because...?
}

关于c++ - 依赖于参数的查找在从另一个 namespace 别名的类型上出现意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37027109/

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