在具有 tempate 基的派生类中使用类型别名模板的声明

Using declaration for type alias template in derived class with tempate base

提问人:Evg 提问时间:2/25/2017 更新时间:10/3/2023 访问量:1222

问:

如果基类依赖于模板参数,则在非限定名称查找中不会检查其作用域。我可以使用声明从基类中引入名称。假设现在我在基类中有一个类型别名模板。是否可以使用该声明将其引入派生类?usingusing

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 行替换为类似于 的(未注释)行 ?Type2Type1

C++ C++11 模板 使用

评论

0赞 L. F. 10/13/2019
不,不允许使用这种语法。不好意思。
0赞 cartoonist 10/30/2019
将模板名称引入派生类是可能的,并且可以很好地与 一起使用。gcc-9.2.0
0赞 Evg 10/30/2019
@cartoonist,它是编译器扩展还是新的C++标准功能?语法是什么?
0赞 Evg 10/30/2019
我知道 C++20 中的可选,但我不明白如何在这里使用它作为模板名称引入。typenameType2
1赞 Evg 10/31/2019
@cartoonist,我的意思是这样简单的东西:,可能带有 s 和 s。using Base<T>::Type2;typenametemplate

答:

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;typenametemplate

我们在声明中不需要这些消歧器,但是当我们想在 中使用时,我们仍然需要:usingType2Derived

  • 消歧器 因为是一个模板,并且依赖于templateType2DerivedT
  • 要指定为类型的消歧器typenameType2<...>

另请参阅:关于依赖名称的 cppreference 文章

评论

0赞 Evg 6/14/2023
不像我的例子那样工作。Type2
0赞 Jan Schultke 6/14/2023
@Evg您仍然需要,并且在 中使用此别名时。我已经调整了答案以涵盖这一点。typenametemplateDerived
0赞 Evg 6/15/2023
这就是问题的重点 - 避免和 .但在这种情况下,您根本不需要,因为将继承自 .还可以尝试添加以强制编译器实例化。typenametemplateusing Base<T>::Type2;Type2BaseDerived<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 问题是您尝试获得更多的通用语法。可悲的是,这是不可能的。解决方案是仅将类型定义与类分开。Type2Derived