我正在编写使用大量模板的代码,而我经常偶然发现如下所示的代码:
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 ++标准中有什么方法可以简化这一点?
答案 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-directive的格式为using namespace please_not_std
,并将please_not_std
命名空间中的内容带到当前范围(这是一种简化)。
using-declaration的格式为using Class::name
,并在当前作用域中引入在其他地方定义的名称。
type alias (C++11)的格式为using new_type = existing_type
,并定义...类型别名。