请考虑以下代码段:
template< typename A, typename B >
struct A
{
public:
typedef std::map< A, B > map;
};
class B
{
public:
B(const ??map) : _map(map) {}
const ??map getMap();
private:
??map _map;
};
int main(){
A<int, int>::map myMap;
B b(myMap); ???
..
..
A<int, int>::map = b.getMap(); ???
}
我想做的是:
我不知道如何做到这一点。 不知何故,模板化的地图应该被包装,B的getMap方法应该返回一个代理对象,从中可以拉出实际地图(使用强制转换?)。
我害怕有许多类被模板化,因为一个成员是通用的,所以传递模板参数整个层次结构。
答案 0 :(得分:3)
您正在寻找的是特质课程。 Andrei Alexandrescu称他们为“else-if-then of types”。
traits类只是携带信息(如类型)和算法(比如说,“advance”)。首先定义一般信息,这些信息将应用于任何类型T
,然后为特定类型U
专门设置traits类,以授予特殊行为。
In your case (an example more complex than it needs to be):
#include<iostream>
#include<map>
template<typename T>
struct container_traits {
using container_t = std::map<int, int>;
};
class Foo {
public:
using key_type = typename container_traits<Foo>::container_t::key_type;
using mapped_type = typename container_traits<Foo>::container_t::mapped_type;
using size_type = typename container_traits<Foo>::container_t::size_type;
Foo() { }
size_type insert(key_type key, mapped_type val) {
m_container.insert(std::make_pair(key, val));
return m_container.size();
}
private:
container_traits<Foo>::container_t m_container;
};
int main() {
Foo f;
std::cout<<f.insert(5, 4)<<std::endl;
}
注意发生了什么:traits类container_traits
类定义“对于每个类型T
,都会有一个名为container_t
的类型,一般来说 - 是map<int, int>
。
如果您之后定义了需要Bar
作为容器的类型map<string, string>
,您只需将traits类重新定义为:
template<>
struct container_traits<Bar> {
using container_t = std::map<string, string>;
};
然后,无论何时拨打container_traits<Bar>::container_t
,您都将检索到正确的地图。
我对traits类的解释不能正确对待我链接的实际文章:阅读它。这是一个非常简单的概念,但它非常强大。现代C ++设计(在通用编程的上下文中)很大程度上依赖于特征类(标准库也是如此)。