Reputation: 60371
Consider the following code:
template <class T>
struct computation {
using type = /* something based on T that takes time to compile */;
};
Now consider two codes:
using x = computation<T>;
and:
using y = typename computation<T>::type;
I am wondering whether the standard implies that:
x
and long compile time for y
computation<T>::type
even if only computation<T>
is called, leading to long compile-time even for x
In other words, I am trying to know if the standard specifies anything that would most likely translate into option A or option B for a "reasonable" compiler implemeter. I know that the standard says nothing about compiler implementation but for example if it requires that ::type
does not have to exist until it's specifically called, that would be in favor of option A.
NOTE: In my experience, I am pretty sure that g++
, clang++
, msvc
, and intel
are following option A), but I have no idea whether it's just by pure luck of it's related to something in the standard.
Upvotes: 1
Views: 94
Reputation: 76678
I am assuming that T
is an actual non-dependent type here and not another template parameter.
The line
using x = computation<T>;
does not cause implicit instantiation of computation<T>
. There is therefore no reason for a compiler to try to compute type
at this point, in particular since any instantiation failure would need to be ignored. The program may not fail to compile if type
's computation would yield an invalid type or would otherwise fail.
The line
using y = computation<T>::type;
does require implicit instantiation of computation<T>
because the scope resolution operator is applied to it. The implicit instantiation includes computation of type aliases inside computation<T>
. The compiler must perform the computation, because if the computation failed or would yield an invalid type, then the program would be ill-formed and the compiler would need to diagnose it.
This doesn't actually dependent on the ::type
part specifically. Even if it was ::type2
for another type alias, the implicit instantiation of the class template specialization will require computation of type
.
Similarly using computation<T>
in any other context requiring it to be complete will require implicit instantiation and therefore computation of type
, e.g.
auto z = computation<T>{};
Upvotes: 3