引用依赖的类型名

refer to a dependent typename

本文关键字:类型 依赖 引用      更新时间:2023-10-16

在以下代码片段中:

#include <map>
template<class T>
struct Base {
  typedef T U;
};
template<class T>
struct Derived: public Base<std::map<int,std::map<int,T>>> {
  typedef typename Base<std::map<int,std::map<int,T>>>::U U; // ugly!
  void F(U u) {};
};
int main(){}

标记的行是丑陋的,还包含重复的信息(如果基类参数的类型改变,这一行也必须改变)。然而,有必要重复这样的声明,否则代码将无法编译。此外,我想避免做一个全局类型定义声明…

是否有一个解决方案来引用在模板依赖基类中定义的类型?

可以将容器类型作为模板参数:

template<class T, class C = std::map<int,std::map<int,T>>>
struct Derived: public Base<C> {
  typedef typename Base<C>::U U;
//...
};

注:

如果你至少使用c++ 11,你可以组合一个函数声明(这里不需要定义)和using声明,如下所示:

#include <map>
#include<utility>
template<class T>
struct Base {
  using U = T;
};
template<typename T>
typename Base<T>::U f(Base<T>);
template<typename T>
using BType = decltype(f(std::declval<T>()));
template<class T>
struct Derived: public Base<std::map<int,std::map<int,T>>> {
  using U = BType<Derived>;
  void F(U u) {};
};
int main(){}

还请注意,typedef s也已被using声明所取代。

问题是非限定名称查找不查找依赖的基类。所以只要限定名称并告诉编译器U将是Derived的成员:

void F(typename Derived::U u) {}

如果你不愿意一次又一次地写出所有的东西,那么使用一个新的成员别名:

using DU = typename Derived::U; // or typedef equivalent