Baykov Nikita
Baykov Nikita

Reputation: 618

The rationale for some of the ADL algorithm steps (C++)

In short, I am trying to understand the behavior of Argument-Dependent Lookup in C++. Some statements in ISO/IEC 14882:2017 (E) regarding ADL are not clear to me. I hope somebody would clarify them to me.

According to standard,

... Furthermore, if T is a class template specialization, its associated namespaces and classes also include: the namespaces and classes associated with the types of the template arguments provided for template type parameters (excluding template template parameters); the namespaces of which any template template arguments are members; and the classes of which any member templates used as template template arguments are members.

The question is why it has to be a class template specialization? Consider the following example:

#include <iostream>                                                             

using namespace std;                                                            

namespace N                                                                     
{                                                                               
    template <typename T>                                                       
    struct A {};                                                                

    template <typename T>                                                       
    void func (const T&) {cout << __PRETTY_FUNCTION__ << endl;}                 
}                                                                               

template <typename T, template <typename> class S>                              
class X {};                                                                     

int main ()                                                     
{                                                                               
    typedef X<int, N::A> XX;                                                    
    func(XX{});                                                                 
}

As far as I can see, it compiles with both g++ and clang++, and I don't have to define something like

template <>                                                                   
class X<int, N::A> {};

to make it work.

Upvotes: 1

Views: 152

Answers (1)

Brian Bi
Brian Bi

Reputation: 119587

See [temp.spec]/4:

An instantiated template specialization can be either implicitly instantiated for a given argument list or be explicitly instantiated. A specialization is a class, function, or class member that is either instantiated or explicitly specialized.

X<int, N::A> is a specialization. If you were to explicitly specialize X for the arguments int and N::A, it would also be a specialization. (In C++20, the term "declared specialization" was introduced to specifically refer to the latter case; [temp.inst]/1.)

So the quoted paragraph applies to an argument of type X<int, N::A>; the namespace N is an associated namespace.

Upvotes: 1

Related Questions