模板基类函数成员的别名

时间:2019-01-29 08:41:33

标签: c++ templates syntax variadic-templates template-meta-programming

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

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 ++标准中有什么方法可以简化这一点?

3 个答案:

答案 0 :(得分:3)

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

您可以通过在相关上下文中使用注入的类名来解决此问题,以便将其查找推迟到实例化之前。像这样:

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

Derived通常可以找到(这是实例化的注入类名),并且已知是依赖的,因此,中间的Base是依赖的,只有在实例化时才会查找Derived,这时所有碱基都已众所周知,可以进行搜索。

答案 1 :(得分:3)

通常,您可以将注入的类名称用于此类目的。这里的问题是,这个注入的类名是模板化基类的成员,因此它是形式上相关的,因此无法被需要在{{1}中选择第一个Base的非限定查找所找到。 }。

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

using Base::Base

template<class T, class V> struct Derived : public Base<T,V> { using Derived::Base::Base; }; 是注入的类名称Derived。这样就找到了,现在我们正在对Derived<T,V>进行合格的查找,因此不再依赖于它。

答案 2 :(得分:2)

您可以使用以下方式定义类型别名:

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

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

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

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

using-declaration的格式为using Class::name,并在当前作用域中引入在其他地方定义的名称。

type alias (C++11)的格式为using new_type = existing_type,并定义...类型别名。

相关问题