c ++访问地图中数组的元素

时间:2012-11-23 10:51:28

标签: c++ arrays map

  

可能重复:
  Using array as map value: Cant see the error

假设我有以下数据结构:

std::map<size_t, double[2] > trace;

如何使用operator []?

访问其元素

基本上我想做类似的事情:

trace[0][0] = 10.0;
trace[0][1] = 11.0;

在编译这些代码行时,我收到以下错误:

/usr/include/c++/4.6/bits/stl_map.h:453:11: error: conversion from ‘int’ to non-scalar type ‘std::map<long unsigned int, double [2]>::mapped_type {aka double [2]}’ requested

评论

3 个答案:

答案 0 :(得分:5)

地图的值类型必须是默认可构造的,使用表达式value_type()才能通过[]访问它们。出于一些神秘的原因,数组类型不是,如C ++ 11 5.3.2 / 2中所规定的那样(我强调):

  

表达式T(),其中T是非数组完整对象类型的简单类型说明符或类型名称说明符...创建指定类型的prvalue,这是价值初始化

编译器在尝试对数组进行值初始化时会发出奇怪的错误;以下内容给出了同样的错误:

typedef double array[2];
array();

我建议使用类型而不是double[2]std::array<double,2>std::pair<double,double>或包含两个双打的struct。这些类型是可复制的,不会在一滴一滴的情况下衰减成指针(失去编译时的大小知识),并且通常比内置数组类型更容易处理。

如果您遇到一个不提供std::array的旧库,那么您可以使用非常相似的Boost.Array,或者编写自己的简单类模板来包装数组。

答案 1 :(得分:1)

你可以包装一个数组:

template<typename T, unsigned int n>
struct ArrayWrapper
{
    T v[n];
    T& operator[](unsigned int i) { return v[i]; } // You can also check for out-of-bounds errors
    const T& operator[](unsigned int i) const { return v[i]; } // You can also check for out-of-bounds errors
};
#include <map>
#include <iostream>
int main()
{
    typedef std::map<size_t, ArrayWrapper<double,2> > Map;
    Map trace;
    trace[1][0] = 42;
    for(Map::const_iterator it = trace.begin(); it != trace.end(); ++it)
        std::cout << "( " << (*it).first
            << ", " << (*it).second[0]
            << ", " << (*it).second[1]
            << ")\n";
}

Live example。否则,如果你有C ++ 11,你应该使用std::array;如果没有,并且你有Boost,你可以使用Boost.Array。

答案 2 :(得分:1)

你的代码编译到:

std::map<size_t, double[2]> trace;

因为double[2]是有效类型。您可以使用任何有效类型声明模板类对象。例如:

template<typename T>
struct X {
  // T t; // this will complain for sure
  void foo () { T t; } // this won't complain unless invoked !!
};
X<void> x;

将编译没有任何问题。
如果你调用x.foo(),编译器会抱怨它。

std::map的情况也是如此。当您调用map::insert()map::operator []等函数时,实际将使用值类型double[2],编译器将开始抱怨,因为double[2]不可复制(异常:我见过一个旧的g ++ 3.x版本,其中数组是可分配和可复制的。)

您可以将数组封装到结构中。

struct D { double d[2]; };

如果你想避免使用原始数组,那么std::array是很好的选择,如评论和其他答案所述。