4

Consider this example code:

template <class T>
using pt_type = typename T::type;

template <class T>
class V {
  using type = int;
  public:
  using pt = pt_type<V>;
};

void g() {
  V<int>::pt a; // Does compile
  pt_type<V<int>> b; // Does not compile
}

V<int>::pt is an alias for pt_type<V<int>>. Nevertheless the fact it is defined depends on the context where it is referred.

Where is it explained in the C++ standard that the substitution of the template parameter by the template argument is performed in the context where is refered the alias specialization?

SU3
  • 5,064
  • 3
  • 35
  • 66
Oliv
  • 17,610
  • 1
  • 29
  • 72

3 Answers3

9

Nowhere. This is core issue 1554.

The interaction of alias templates and access control is not clear from the current wording of 14.5.7 [temp.alias]. For example:

template <class T> using foo = typename T::foo;

class B {
  typedef int foo;
  friend struct C;
};

struct C {
  foo<B> f;    // Well-formed?
};
kmdreko
  • 42,554
  • 6
  • 57
  • 106
T.C.
  • 133,968
  • 17
  • 288
  • 421
-1

using pt_type = typename T::type; can't access V::type becasue type is private.

The following works:

template <class T>
using pt_type = typename T::type;

template<class T>
class V
{
  public:
    using type = int;
    using pt = pt_type<V>;
};

void g()
{
    V<int>::pt a; //Do compile
    pt_type<V<int>> b; //Do not compile
}
Caleb
  • 284
  • 2
  • 7
  • Please read the code one more time. pt_type do access V::type in the definition of V::pt. – Oliv Jan 25 '18 at 23:11
-1

In V::pt you are accessing to your "own" type and you can do it, but the private makes it impossible in the second case. So V::pt crates an instanciation of pt_type passing your private type int. But in the second case you try directly and it does not work,

LeDYoM
  • 949
  • 1
  • 6
  • 21
  • OK This is second out of subject answer, I am waiting for a c++ standard quotation – Oliv Jan 25 '18 at 23:12
  • What standard quotation? That you cannot access private members? – LeDYoM Jan 25 '18 at 23:15
  • And you? Make it public and it works. As @Caleb already shown you. This is not context dependant because you are referring to them in different paths. Actually, with GCC 7.2 none of your 2 lines even work. As normal. – LeDYoM Jan 25 '18 at 23:35