当编译该snipet在godbolt,大多数编译器产生两个不同的get方法(在装配窗口不同的符号):
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;
}
Run Code Online (Sandbox Code Playgroud)
CurrentField即使是别名,我也看到了符号。只有gcc抱怨重新定义(如预期)。
关于type_alias的 C ++参考说
它没有引入新的类型
所以我认为它不应该这样表现,我错了吗?
实际上,大多数编译器的行为似乎是将别名模板替换为类Trait
template<typename T>
struct CurrentField
{
alias type = Field<T> ;
};
Run Code Online (Sandbox Code Playgroud)
编辑:
这是我尝试在Godbolt上实现的目标的更具代表性的示例。请注意,由于只有一个源并且没有链接,所以它可以编译,但msvc程序集显示它既生成了预先实例化的签名又生成了用户调用签名。
它分为4个部分:1.具有多种模板的容器库,如StackField和HeapField; 2.具有成员方法(如size)的实用程序库,其中字段作为模板参数(如您建议的第二种解决方法); 3.隐藏实现,并且在c ++中预先针对不同的字段进行了说明。4.用户使用诸如AField和的别名将应用程序A和B与此库链接BField …