Аргументы шаблона C ++ - PullRequest
       19

Аргументы шаблона C ++

0 голосов
/ 13 марта 2012

У меня есть шаблон, который делает вектор. Конструктор по умолчанию назначает n идентичных элементов. Второй конструктор создает вектор с заданными аргументами. В связи с тем, что второй конструктор использует конструктор по умолчанию для определения вектора, я могу только привести аргументы о том, сколько элементов будет в этом векторе и каково их значение.

    public:
      vector<float> coords;
      Vector<n> (){
      coords.assign(n, 0.0);
      }
      Vector<n> (vector<float> crds){
          coords.assign(crds.size(),0.0);
}   

В идеале второй конструктор должен взять crds и проверить его размер. Затем назначьте нули столько раз, сколько размер crds . Он работает хорошо, если размер равен 2. Но если размер больше или меньше 2, он выдает ошибки.

Если я получу эту работу, я вставлю каждое значение в crds и вытолкну ненужные нули. Но на данный момент я не могу найти другое решение. + Я не нашел никакой другой векторной функции stl, которая бы подходила мне лучше, чем назначать.

Код, с помощью которого я проверяю результат:

    Vector<2> v2 (vector<float>(2,3)); 

Ответы [ 2 ]

2 голосов
/ 13 марта 2012

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

#include <vector>
#include <algorithm>
#include <cassert>

// untested
template <std::size_t n>
struct Vector {
  std::vector<float> coords;
  Vector() : coords(n, 0.) {}
  Vector(const std::vector<float>& crds)
    : coords(crds.begin(),
        crds.begin()+std::min(n, crds.size())) {
    // resize() extends coords with 0.0 values
    coords.resize(n);
  }
};

int main () {
  std::vector<float> v(3);
  Vector<6> V(v);
  assert(V.coords.size() == 6);
}

РЕДАКТИРОВАТЬ : в соответствии с объясненными требованиями:

#include <vector>
#include <algorithm>
#include <cassert>

// untested
template <std::size_t n>
struct Vector {
  std::vector<float> coords;
  Vector() : coords(n, 0.) {}
  Vector(const std::vector<float>& crds)
    : coords(crds) { }
};

int main () {
  Vector<6> V1;
  Vector<6> V2(std::vector<float>(3, 2.));
  Vector<6> V3(std::vector<float>(10, 3.));
  assert(V1.coords.size() == 6);
  assert(V2.coords.size() == 3);
  assert(V3.coords.size() == 10);
}

EDIT : Отвечая на требование для списка инициализатора.

Если ваш компилятор предоставляет функции c ++ 11, вы можете инициализировать либо std::vector, либо Vector из списка значений, используя std::initializer_list.

#include <vector>
#include <algorithm>
#include <cassert>
#include <initializer_list>

// untested
template <std::size_t n>
struct Vector {
  std::vector<float> coords;
  Vector() : coords(n, 0.) {}
  Vector(const std::vector<float>& crds)
    : coords(crds) { }
  Vector(std::initializer_list<float> list)
    : coords(list) {}

};

int main () {
  Vector<6> V1;
  Vector<6> V2(std::vector<float>(3, 2.));
  Vector<6> V3(std::vector<float>(10, 3.));
  Vector<6> V4(std::vector<float> ({1, 2, 3, 4}));
  Vector<6> V5({1, 2, 3, 4});
  assert(V1.coords.size() == 6);
  assert(V2.coords.size() == 3);
  assert(V3.coords.size() == 10);
  assert(V4.coords.size() == 4);
  assert(V5.coords.size() == 4);
}
0 голосов
/ 13 марта 2012

Если я правильно понимаю, что вы хотите сделать, просто использование стандартных векторных конструкторов должно делать то, что вы хотите:

#include <vector>

template <int N>
class Vector {
public:
  std::vector<float> coords;

  Vector ()
    : coords(N, 0.0f)
  {}

  Vector (const std::vector<float> & crds)
    : coords(crds)
  {}
};

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

...