模板基类函数成员的别名



我正在编写使用大量模板的代码,我经常偶然发现如下所示的代码:

template<class T, class V>
struct Base {  Base(int a) {} };
template<class T, class V>
struct Derived : public Base<T,V>
 {
 using Base<T,V>::Base; // [1] ok it works
 using Base::Base; // [2] Does not work  
 };

想想当你写而不是T更有意义的名字时,[1]语句变得太长了......有没有办法使用像[2]这样的语句?或者有什么东西可以在即将到来的C++标准中简化这一点吗?

通常,您可以使用注入的类名来实现此类目的。这里的问题是这个注入的类名是模板化基类的成员,因此它是形式依赖的,因此需要拾取using Base::Base中第一个Base的非限定查找找不到它。

但是我们可以在这里操纵查找的工作方式:

template<class T, class V>
struct Derived : public Base<T,V>
{
    using Derived::Base::Base;
};

Derived 是注入的类名 Derived<T,V> 。所以找到了,现在我们正在对Base进行合格的查找,所以它不再是问题。

只使用 Base::Base 的问题在于名称 Base(在左侧)应该是父Base<T, V>的注入类名,但由于该父级是依赖的,因此不会搜索名称,因此找不到注入的类名。

您可以通过在依赖上下文中使用注入的类名来解决此问题,以便将其查找推迟到实例化。喜欢这个:

template<class T, class V>
struct Derived : public Base<T,V>
 {
 using Derived::Base::Base;
 };

Derived是正常找到的(它是这个实例化的注入类名),并且已知是依赖的,所以中间的Base是依赖的,只有在实例化Derived时才会被查找,此时所有碱基都是完全已知的,可以搜索。

可以使用以下命令定义类型别名:

template<class T, class V>
struct Derived : public Base<T,V>
{
    using BaseClass = Base<T,V>;
    using BaseClass::Base;
};

using关键字在C++中有三个含义。它可以介绍:

  • 一个使用指令
  • 使用声明
  • 或类型别名。

using-指令的形式为 using namespace please_not_std,并将 please_not_std 命名空间中的任何内容带到当前范围(这是一种简化)。

using-声明的形式为 using Class::name,并将在当前作用域中其他位置定义的名称引入。

类型别名 (C++11) 具有 using new_type = existing_type 的形式并定义 ...类型别名。

最新更新