Reputation: 618
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
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