0

考虑这个片段:

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 获取通用地图返回

我不知道如何做到这一点。应该以某种方式包装模板化地图,并且 B 的 getMap 方法应该返回一个代理对象,可以从中提取实际地图(使用演员表?)。

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

4

1 回答 1

3

您正在寻找的可能是特征类。Andrei Alexandrescu 称它们为“ else-if-then 类型”。

特征类只携带信息(如类型)和算法(如“高级”)。您首先定义适用于任何类型的一般信息,T然后将特征类专门U用于授予特殊行为的特定类型。

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定义了“对于每个 type T,都会有一个名为 的类型container_t,它——通常——是一个map<int, int>.

如果您随后定义了一个Bar需要 amap<string, string>作为容器的类型,您可以简单地将特征类重新定义为:

template<>
struct container_traits<Bar> {
 using container_t = std::map<string, string>;
};

然后,无论何时调用container_traits<Bar>::container_t,您都会检索到正确的地图。

我对特征类的解释不能对我链接的实际文章做出公正的解释:阅读它。这是一个非常简单的概念,但它非常强大。现代 C++ 设计(在泛型编程的上下文中)严重依赖于特征类(标准库也是如此)。

于 2013-08-05T18:27:07.300 回答