Vincent
Vincent

Reputation: 60371

When does the compiler need to compute an alias?

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:

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

Answers (1)

user17732522
user17732522

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

Related Questions