在C++20中,<tuple>中的get<>()函数不再位于命名空间std中。为什么?

问题描述 投票:0回答:1

以下代码不能在 C++17 中编译,但可以在 C++20 中编译:

#include <tuple>

int main() {

    auto t = std::make_tuple(1, 2);
    get<0>(t); // no std:: required!

    return 0;
}

由于这适用于 g++ 和 clang++ 以及

-stdlib=libc++
-stdlib=libstdc++
,甚至在 msvc 中也适用于
/std:c++20
,我想知道这是否是一个“功能”。这背后的理由是什么?除此之外还有对全局命名空间的更多污染吗?

c++ get c++20 global-namespace
1个回答
0
投票

std::get
是通过与参数相关的查找找到的,因为
t
具有类型
std::tuple
,它与您要使用的
std::get
重载位于同一命名空间范围内。

在 C++17 中失败的原因与是否找到

std::get
无关,而是与确定
<
后面的
get
是否为小于运算符或开始的规则有关。模板参数列表。在 C++20 之前,如果通过通常的非限定(非 ADL)查找根本找不到
<
之前的非限定名称,则程序格式错误。从 C++20 开始,假定在这种情况下引入模板参数列表。

例如,如果您添加模板

template<typename T>
void get();

进入全局命名空间范围,那么

<
也将被假定引入模板参数列表,因为这个函数模板是通过通常的非限定查找找到
get
的,即使在 C++17 中也是如此。

© www.soinside.com 2019 - 2024. All rights reserved.