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