2012-06-13 5 views
0

Я хотел бы написать некоторый класс, который отображает int на что-то, используя шаблоны. Что я имею в виду, как правило, два варианта:map of ints to class (template)

1. unsigned int -> double   (scalar) 
2. unsigned int -> double[N]  (vector of length N; N is the same for each int) 

Я пишу класс вокруг

template <class T> 
class int2type_storage { 
    public: 
    .... 
    private: 
    typename std::map<unsigned int,T> map_; 
} 

При первом случае использование прост:

int2type_storage<double> map1; 

вопрос является, что является наиболее эффективным способом/объектом для второго случая? я думал сделать что-то вроде

int2type_storage< std::vector<double> > 

, но у меня есть ощущение, что это будет неоптимальным. Другой вариант для хранения указателей

int2type_storage< double* > 

но у меня есть проблема, которую я должен выделить память для N элементов за пределами карты класса и заботиться, чтобы освободить его позже.

EDIT1: Спасибо, ребята, за ответ, мне жаль, что я не могу отметить два ответа как правильные.

edit2:

Я выполнил все, но мой линкер не может найти функции:

undefined reference to `int2type_storage<std::tr1::array<double, 4ul> >::init(int, int)' 

.h:

template <class T> 
class int2type_storage { 
public: 
    int2type_storage() {}; 
    ~int2type_storage() {}; 

    void init(const int number, const int index); 
     ... 
private: 
    int cur_index_; 
    typename std::map<unsigned int, T>::iterator iterator_; 
    typename std::vector<std::map<unsigned int,T> > map_vector_; 
    bool zero_initialized; 
}; 

.cpp:

template<class T> 
void int2type_storage<T>::init(const int length, const int max_index) { 
    map_vector_.resize(length); 
} 

использование:

int2type_storage< std::tr1::array<double, 4> > w_map_; 

что не так?

+0

Я сомневаюсь, что вам когда-либо придется переключать векторы на указатели, чтобы повысить производительность. – chris

+0

Единственная причина, по которой я не буду использовать векторы, это то, что у них нет размера N. Но я не буду беспокоиться о соображениях производительности перед профилированием. – juanchopanza

ответ

4

Assumming N известно во время компиляции, вы могли бы использовать std::array<double,N>:

int2type_storage< std::array<double, N> > 

Я не уверен, что причины int2type_storage обертки, но вы также можете использовать шаблон C++ 11 ЬурейеЕ:

template <typename T, int N> 
using int2type_storage = std::map<unsigned int, std::array<T,N>>; 
+0

причиной для обертки являются еще более задействованные функции для получения/установки элементов, поиска и т. Д. Что не касается проблемы. У меня нет C++ 11, я на Ubuntu и компилирую код с помощью mpiC++. Компилятор также жалуется, что массив не является членом std (i включил '') – Denis

+0

@Denis, тогда вы должны использовать 'std :: tr1 :: array' для первой части, но вы не можете сделать вторую (но, похоже, вы В любом случае, это не нужно. – juanchopanza

+0

Я пытаюсь использовать ваше решение, но не могу заставить его работать. Можете ли вы посмотреть PLS? – Denis

3

Если у вас есть C++ 11, std::array является лучшим, и есть также Boost.Array.

Если вы этого не сделаете, то вы можете написать что-то вроде:

template <size_t N> 
struct Doubles { 
    double data[N]; 
}; 

Тогда либо непосредственно использовать .data для доступа к нему, или добавить столько функций-членов и оператор перегрузки, как вы хотите. Если вы добавите правильные, то в итоге у вас будет std::array.

Главное разумное использование для double* - это если вы копируете карты (или иначе имеете несколько карт), и хотите, чтобы они ссылались на одни и те же данные.Но, как вы уже знаете, это создает проблему управления ресурсами, поэтому вы можете рассмотреть shared_array<double>. Вы также можете рассмотреть возможность обмена данными.

Существует также специальный случай, когда элементы C++ 03 копируются в контейнеры, тогда как в C++ 11 есть потенциальная эффективность, перемещая их в контейнер в некоторых случаях. Но массивы (включая std::array и мой класс выше) не могут быть эффективно перемещены. Если N большой, и происходит много копий, то потенциально что-то эффективно подвижное может работать лучше, поэтому вы можете снова рассмотреть std::vector.

+0

спасибо. Я думаю, это именно то, что я искал. – Denis