Convert Std::vector p/ Std::array implicitly?

Asked

Viewed 34 times

2

How do p/ extend the std::vector so that there is an implicit conversion of std::array for std::vector?

Imagine I have this:

template <class T, int N>
std::array<T, N> vector_to_array (std::vector<T> x) {
  std::array<T,N> y;
  std::copy_n(x.begin(), N, y.begin());
  return y;
}

std::array<int,2> times2 (std::array<int, 2> x) {
  x[0] = x[0]*2;
  x[1] = x[1]*2;
  return x;
}

void times2vector (std::vector<int>  x) {
  auto res = times2(vector_to_array<int, 2>(x));
  std::cout << res[0] << std::endl;
  std::cout << res[1] << std::endl;
}

I wanted to avoid the explicit call from vector_to_array<int, 2>(x) and make it happen implicitly.

  • 1

    You can inherit in another class and create an operator from cast, but I guess it doesn’t make up, everybody’s running from doing Casts implicit, needs to be case well thought out, in general only being in the type from the beginning and not making inheritance, gives more problems than solution.

1 answer

2


In that case, the best solution seems to me to simply make a Function overloading.Check out:

std::array<int,2> times2(std::array<int, 2> x) {
  x[0] = x[0]*2;
  x[1] = x[1]*2;
  return x;
}

std::array<int,2> times2 (std::vector<int> x){
   return times2(vector_to_array<int, 2>(x));
}

void times2vector (std::vector<int>  x) {
  auto res = times2(x);
  std::cout << res[0] << std::endl;
  std::cout << res[1] << std::endl;
}

However, that is not what you asked for and I suspect you have at some point worked with that possibility. However, the solution in the way you want to encounter two serious problems, the first of these problems stems from the unpredictability of extending (or inheriting) the std::vector

I particularly do not know if there are clear rules on the inheritance of most classes of standard library or if it is not defined and is therefore something that depends on implementation. In this regard, it goes without saying that if the implementation uses, for example, a private Member tout est Perdu. Friend classes and functions are also problematic and I believe there are other cases. An example:

class myvector: public std::vector<int>{};

int main(){
   //essa parte funciona
   myvector a0;
   std::vector<int> a1;
   a0.push_back(42);
   a1.push_back(21);

   std::cout << "myvector: " << a0[0] << "\t std::vector: " << a1[0] << '\n';

   //mas aqui a vaca vai para o brejo
   std::vector<int> b0{2, 4, 5};
   myvector b1{2, 4, 5}; //no matching function for call to ...

   return 0;
}

The second problem is related to implicit conversion. In most cases, it is perfectly possible to use the implicit Conversion Operator to create a user-defined implicit conversion. See the example below:

#include <iostream>

class A{
public:
   int i = 11;
   int j = 13;
};

class B{
public:
   char i = 'S';
   //cria uma conversão implicita de A para B
   operator A() const {return A{42, 45};}
};

//note que a função somente recebe A como parâmetro
void print_number(A a){
   std::cout << a.i << '\n';
}

int main(){
   A a;
   B b;
   print_number(a);
   print_number(b);// mas com o "operator A()", agora a função aceita B numa boa
   return 0;
}

/*output:
>> 11
>> 42
*/

However, in the case of std::array, this is extremely problematic because it is not only a template but a template in which one of the parameters is not even a type and it simply does not match well with Operators. For example, this is definitely not going to work:

template <class T, int N>
std::array<T, N> vector_to_array (std::vector<T> x) {
  std::array<T,N> y;
  std::copy_n(x.begin(), N, y.begin());
  return y;
}

class mvector : public std::vector<int> {
   operator std::array<T, int N>() const { //ops... template argument 2 is invalid
      return vector_to_array<T, N>(*this);
   }
};

Finally, some websites consulted for later reading and workarounds (unfortunately, all in English, as well as workarounds which means 'alternative solutions' ):

https://en.cppreference.com/w/cpp/language/cast_operator
https://stackoverflow.com/questions/1762049/templated-operator-overload-c
https://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from-stdvector

Browser other questions tagged

You are not signed in. Login or sign up in order to post.