返回一个通用容器而不模板化该类

时间:2013-08-05 18:07:27

标签: c++ templates containers

请考虑以下代码段:

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(); ???
}

我想做的是:

  1. 将通用地图注入B
  2. B类不应该是模板类
  3. 从B获取通用地图
  4. 我不知道如何做到这一点。 不知何故,模板化的地图应该被包装,B的getMap方法应该返回一个代理对象,从中可以拉出实际地图(使用强制转换?)。

    我害怕有许多类被模板化,因为一个成员是通用的,所以传递模板参数整个层次结构。

1 个答案:

答案 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 ++设计(在通用编程的上下文中)很大程度上依赖于特征类(标准库也是如此)。