When compiling this snipet in godbolt, most compilers generate two different get
methods (different symbol in the assembly window):
template<typename T>
struct Field { T impl; };
template<typename T>
using CurrentField = Field<T>;
template<template <typename> class F>
struct Encompassing { F<int> member; };
auto get(Encompassing<Field> const& instance)
{
return instance.member.impl;
}
auto get(Encompassing<CurrentField> const& instance)
{
return instance.member.impl;
}
I see CurrentField
in symbols even if it is an alias. Only gcc complains about redefinition (as expected).
C++ reference on type_alias says
It does not introduce a new type
so I think it is not supposed to behave like this, am I wrong?
Actually most compiler seems to behave like the alias template was substituted with a class Trait like
template<typename T>
struct CurrentField
{
alias type = Field<T> ;
};
Edit:
Here is a more representative example of What I try to achieve on Godbolt. Note that it compiles since there is a single source and no linking but the msvc assembly shows it generated both the pre-instantiated signatures and user calls signatures.
There are 4 parts:
1. a container library with multiple kind of templates like StackField
and HeapField
,
2. an utility library with member methods like size, with the field as template argument (like the second workaround you proposed),
3. implementations are hidden and pre-instantiated in the c++ for different fields
4. users link their application A and B against this library, using aliases like AField
and BField
. It works with gcc but link fails in msvc because the signature of my pre-instantiated implementations and the users calls don't match