在以下代码段中:
#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(){}
标记的行很难看并且还包含重复的信息(如果Base类参数的类型发生更改,则此行也必须更改)。但是必须有这样的重复声明,否则代码不会编译。另外,我想避免制作全局typedef声明......
是否有解决方案来引用模板依赖基类中定义的类型?
答案 0 :(得分:4)
您可以将容器类型作为模板参数传递:
template<class T, class C = std::map<int,std::map<int,T>>>
struct Derived: public Base<C> {
typedef typename Base<C>::U U;
//...
};
P.S。同样的事情可以在基类中完成。
答案 1 :(得分:3)
如果你至少可以使用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
也已被使用声明替换。
答案 2 :(得分:1)
问题是非限定名称查找不会查看依赖基类。因此,只需限定名称并告诉编译器U
将成为Derived
的成员:
void F(typename Derived::U u) {}
如果你不喜欢一遍又一遍地写出整件事,那就使用一个新的成员别名:
using DU = typename Derived::U; // or typedef equivalent