Mir*_*ode 3 c++ get global-namespace c++20
以下代码不能在 C++17 中编译,而是在 C++20 中编译:
#include <tuple>
int main() {
auto t = std::make_tuple(1, 2);
get<0>(t); // no std:: required!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于这适用于 g++ 和 clang++ 以及两者-stdlib=libc++,-stdlib=libstdc++甚至在 msvc 中/std:c++20,我想知道这是否是一个“功能”。这背后的理由是什么?除此之外还有对全局命名空间的更多污染吗?
std::get是通过参数相关查找 (ADL) 找到的,因为t它的类型是类模板的特化,该类型与您要使用的重载std::tuple位于同一命名空间范围内。std::get这是 C++ 中一直存在的行为,并且是使运算符重载以及其他可自定义函数调用(如swap.
它在 C++17 中失败的原因与是否找到无关,而是与确定以下内容是否为小于运算符或模板参数列表开头std::get的规则有关。在 C++20 之前,如果通过通常的非限定(非 ADL)查找根本找不到 之前的非限定名称,则程序格式错误。从 C++20 开始,假定在这种情况下引入模板参数列表。<get<
例如,如果您添加名为 的函数模板get,无论签名如何,例如
template<typename T>
void get();
Run Code Online (Sandbox Code Playgroud)
进入你的全局命名空间范围,然后<也将被假定引入一个模板参数列表,因为这个函数模板是get通过通常的非限定查找找到的,即使在 C++17 中也是如此。然后 ADL 像往常一样应用于调用(在每个 C++ 版本中始终以这种方式工作)并且std::get也将被发现为候选。
| 归档时间: |
|
| 查看次数: |
110 次 |
| 最近记录: |