gpt4 book ai didi

c++ - 两阶段函数模板编译 : not *only* ADL is employed in the 2nd phase?

转载 作者:行者123 更新时间:2023-12-03 18:12:14 24 4
gpt4 key购买 nike

我想知道为什么 following code编译。

#include <iostream>

template<class T>
void print(T t) {
std::cout << t;
}

namespace ns {
struct A {};
}

std::ostream& operator<<(std::ostream& out, ns::A) {
return out << "hi!";
}

int main() {
print(ns::A{});
}

我的印象是,在实例化点不合格的依赖名称仅通过 ADL 查找 - 这不应该考虑全局 namespace 。我错了吗?

最佳答案

这是一个有趣的案例。您描述的名称查找的工作原理总结如下:

[temp.dep.candidate] (emphasis mine)

1 For a function call where the postfix-expression is a dependent name, the candidate functions are found using the usual lookup rules ([basic.lookup.unqual], [basic.lookup.argdep]) except that:

  • For the part of the lookup using unqualified name lookup, only function declarations from the template definition context are found.

  • For the part of the lookup using associated namespaces ([basic.lookup.argdep]), only function declarations found in either the template definition context or the template instantiation context are found.

If the call would be ill-formed or would find a better match had the lookup within the associated namespaces considered all the function declarations with external linkage introduced in those namespaces in all translation units, not just considering those declarations found in the template definition and template instantiation contexts, then the program has undefined behavior.



我强调的一点是问题的关键。 “仅 ADL”的描述是针对来自 foo(bar) 的函数调用的。 !它没有提到由重载运算符产生的调用。我们知道调用重载运算符等同于调用函数,但该段落以特定形式讲述表达式,仅是函数调用的形式。

如果要将您的功能模板更改为
template<class T> 
void print(T t) {
return operator<< (std::cout, t);
}

现在通过后缀表达式表示法调用函数,然后 wo 并且看: GCC emits an equivalent error to Clang .它可靠地实现了上面的段落,只是在涉及重载的运算符调用时则不然。

那么这是一个错误吗?我会说是的。目的肯定是像命名函数一样找到重载运算符(即使从它们各自的表达式形式调用)。所以需要修复 GCC。但该标准也可以对措辞稍作澄清。

关于c++ - 两阶段函数模板编译 : not *only* ADL is employed in the 2nd phase?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58793092/

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