Constructor instantiation in a world of guaranteed copy elision

  • A+

Consider this example:

template <typename T> using type = typename T::type;  template <typename T> struct A {     A(type<T>); };  A<int> f(); A<int> g() { return f(); } 

Neither gcc nor clang compile this code due to int not having a nested type typedef. But why is that constructor being instantiated at all? f() is a prvalue of the same type as the return of g(), there shouldn't even be a move there. What is causing us to instantiate the bad constructor?


The constructor is a bit of a red herring. The same would happen if it was any other member function.

template <typename T> struct A {     void foo(type<T>); // Same error }; 

This is on account of [temp.inst]/2

The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, default arguments, or noexcept-specifiers of the class member functions, [...]

The declaration is instantiated, so type<T> has to be well-formed.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: