简体   繁体   中英

C++ template arguments

I have a template that makes a vector. The default constructor assigns n identical valued elements. The second constructor makes a vector with given arguments. Due to the fact that the second constructor uses the default constructor to define the vector, I can only give arguments about how many elements will be in this vector and what is their value.

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

Ideally the second constructor should take crds and check it size. Then assign zeros as many times as the size of crds . It works well if the size is 2. But if the size is more or less than 2 it gives out errors.

If I get this working then I would insert every value in crds and pop the unnecessary zeros. But at the moment I can't figure out another solution. + I didn't find any other vector stl function that would suit me better than assign.

The code with which I check the result is

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

This does what I think you are asking for. The code complexity in the 2nd constructor ensures that we don't copy extra values in, just to erase them.

#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);
}


EDIT : responding to explained requirements:

 #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 : Responding to requirement for initializer list.

If your compiler provides c++11 features, you can initialize either std::vector or Vector from a list of values, using 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); } 

If I understand correcly what you want to do, simply using standard vector constructors should do what you want:

#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)
  {}
};

But, as emphasized by others in the comments, this seems to be poorly designed (in particular, I fail to understand why the role of N in both constructors is so asymmetric)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM