提问人:Evg 提问时间:2/25/2017 更新时间:10/3/2023 访问量:1222
在具有 tempate 基的派生类中使用类型别名模板的声明
Using declaration for type alias template in derived class with tempate base
问:
如果基类依赖于模板参数,则在非限定名称查找中不会检查其作用域。我可以使用声明从基类中引入名称。假设现在我在基类中有一个类型别名模板。是否可以使用该声明将其引入派生类?using
using
template<class T>
struct Base
{
using Type1 = int;
template<typename S>
using Type2 = S;
};
template<class T>
struct Derived : Base<T>
{
using typename Base<T>::Type1; // Fine
//using Type1 = typename Base<T>::Type1; // Also fine
template<typename S>
using Type2 = typename Base<T>::template Type2<S>;
};
是否可以将 for 行替换为类似于 的(未注释)行 ?Type2
Type1
答:
0赞
Jan Schultke
6/14/2023
#1
template<class T>
struct Derived : Base<T>
{
using Base<T>::Type2;
void foo() {
// Using the Type2 alias template
// inside our class to declare a local variable.
typename Derived::template Type2<int> i;
}
};
// Using the Type2 alias template
// outside the class to declare another type.
using X = Derived<int>::Type2<int>;
这是正确的语法,所有支持 C++11 的编译器都应该允许这样做。请参阅此处的现场演示。
我的意思是这样简单的东西:,可能带有 s 和 s。
using Base<T>::Type2;
typename
template
我们在声明中不需要这些消歧器,但是当我们想在 中使用时,我们仍然需要:using
Type2
Derived
- 消歧器 因为是一个模板,并且依赖于
template
Type2
Derived
T
- 要指定为类型的消歧器
typename
Type2<...>
评论
0赞
Jan Schultke
6/14/2023
@Evg您仍然需要,并且在 中使用此别名时。我已经调整了答案以涵盖这一点。typename
template
Derived
0赞
Evg
6/15/2023
这就是问题的重点 - 避免和 .但在这种情况下,您根本不需要,因为将继承自 .还可以尝试添加以强制编译器实例化。typename
template
using Base<T>::Type2;
Type2
Base
Derived<int> d; d.foo();
foo()
0赞
Jan Schultke
6/15/2023
@Evg你问的是不可能的。无法创建一个 using 声明来消除我们引入范围的成员是否是模板的歧义。只有语法可以消除类型的歧义。查看 eel.is/c++draft/namespace.udecl#nt:using-declaratorusing typename Base<T>::Type1;
0赞
Swift - Friday Pie
10/3/2023
#2
这种语法解决的问题是,可能用作基类型的类型可以在此定义之后但在实例化之前进行专精细化。Base<T>
Derived
大多数时候,只要是模板,这样的语法就可以工作。这里可能存在的 XY 问题是您尝试获得更多的通用语法。可悲的是,这是不可能的。解决方案是仅将类型定义与类分开。Type2
Derived
评论
gcc-9.2.0
typename
Type2
using Base<T>::Type2;
typename
template