Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

In C++20, the get<>() function inside <tuple> is no longer in namespace std. Why?

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

#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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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.

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.

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

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading