gpt4 book ai didi

In C++20, the get<>() function inside is no longer in namespace std. Why? [duplicate](在C++20中,中的get<>()函数不再位于名称空间std中。为什么?[复制])

转载 作者:bug小助手 更新时间:2023-10-24 22:12:49 24 4
gpt4 key购买 nike




The following code does not compile in C++17 but from C++20 on:

以下代码不能在C++17中编译,而是从C++20开始编译:


#include <tuple>

int main() {

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

return 0;
}

Since this works with both g++ and clang++ and both -stdlib=libc++ and -stdlib=libstdc++ and even in msvc with /std:c++20, I wonder whether this is a "feature". What is the rationale behind this? Is there more pollution to the global namespace besides this?

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


更多回答

I disagree with the duplicate mark, as ADL is only half of the explanation... But since there is already an excellent answer, it doesn't really matter.

我不同意重复标记,因为ADL只是解释的一半…但既然已经有了一个很好的答案,这实际上并不重要。

优秀答案推荐

std::get is found by argument-dependent lookup (ADL), because t has a type that is a specialization of the class template std::tuple which is located in the same namespace scope as the std::get overload you want to use. This is behavior that has always existed in C++ and is fundamental to making operator overloading work, as well as other customizable function calls like swap.

Std::Get是通过参数相关查找(ADL)找到的,因为t的类型是类模板std::tuple的专门化,它位于与要使用的std::Get重载相同的命名空间作用域中。这是C++中一直存在的行为,是使操作符重载以及其他可定制函数调用(如SWAP)工作的基础。


The reason it fails in C++17 has nothing to do with whether std::get is found, but rather with the rules that determine whether or not the < following get is the less-than operator or the start of an template argument list. Before C++20, if the unqualified name before the < wasn't found at all by usual unqualified (non-ADL) lookup, the program was ill-formed. Since C++20 it is assumed to introduce a template argument list in this situation.

它在C++17中失败的原因与是否找到std::GET无关,而是与确定<后面的GET是小于操作符还是模板参数列表的开始的规则有关。在C++20之前,如果通过通常的非限定(非ADL)查找根本找不到<前面的非限定名称,那么程序就是格式错误的。从C++20开始,假设在这种情况下引入模板参数列表。


For example, if you add a function template named get, regardless of signature, e.g.

例如,如果添加一个名为GET的函数模板,而不考虑签名,例如


template<typename T>
void get();

into your global namespace scope, then < will also be assumed to introduce a template argument list because this function template is found for get by usual unqualified lookup, even in C++17. Then ADL applies to the call as usual (this has always worked this way in every C++ edition) and std::get will be found as candidate as well.

在您的全局命名空间作用域中,则还将假定<引入一个模板参数列表,因为这个函数模板是通过通常的非限定查找为GET找到的,甚至在C++17中也是如此。然后,ADL照常应用于调用(这在每个C++版本中总是以这种方式工作),并且STD::GET也将被发现为候选者。


更多回答

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