jeudi 31 mai 2018

candidate function not viable: no known conversion from std::vector

First, The title probably may not reflect the current question, so please feel free to change. Assuming I have the following classes;

#include  <iostream>
#include <vector>

template <typename K, class V>
class A {
public:
  K x;
  V y;
  A(K x, V y):x(x), y(y) {}
  void print(A<K, V>& z) {
    std::cout << x + z.x << "-" << y + z.y << std::endl;
  }
  void print(std::vector<A<K,V>> z) {
    for(auto& i:z) {
      print(i);
    }
  }
};

class B:public A<int, std::string> {
public:
  B():A(0, "zero") {}
  B(int x, std::string y):A(x, y) {}
};

void test() {
  B b1(1, "one");
  B b2(2, "two");
  B b3(3, "three");
  B b4(4, "four");
  B b5(5, "five");
  b5.print(b1);
  //
  std::vector<B> c;
  c.push_back(b1);
  c.push_back(b2);
  c.push_back(b3);
  c.push_back(b4);
  b5.print(c);
}

I get the following error at last last line (b5.print(c));

test_class.cpp:40:6: error: no matching member function for call to 'print'
  b5.print(c);
  ~~~^~~~~
test_class.cpp:10:8: note: candidate function not viable: no known conversion from 'std::vector<B>' to 'A<int, std::__1::basic_string<char> > &' for 1st argument
  void print(A<K, V>& z) {
       ^
test_class.cpp:13:8: note: candidate function not viable: no known conversion from 'vector<B>' to 'vector<A<int, std::__1::basic_string<char> >>' for 1st argument
  void print(std::vector<A<K,V>> z) {
       ^
1 error generated.

I basically expect an implicit conversion from vector<B> to std::vector<A<int,std::string>> but it is not. Hence, I came up with two solutions to the issue.

  1. Define typedef std::vector<A<int,std::string>> MyWeirdVector; in class A and use se B::MyWeirdVector c; instead of std::vector<B> c;.
  2. Define each print function as template <typename U> in A class and accept typename U as argument.

Both solutions has its own drawback. In first, I have to instantiate c as B::MyWeirdVector and in second, I don't (feel like) have a type safety. Second solutions works even if I don't define type in <>.

So, is there an elegant solution to this issue like to let implicit type conversion from std::vector<B> to std::vector<A<int,std::string>>?

Aucun commentaire:

Enregistrer un commentaire