-2

I am fairly new to C++ and templates. I dont expect the reason why it doesnt work to be very complex, but I'm just not getting it.

void print(vector<> v) {
    return;
}

does not compile with the error

error: wrong number of template arguments (0, should be at least 1)

however

void print(vector<int> v) {
    return;
}

doesn't yield such an error.

Why is that?

  • Because you need to provide the template argument...? The compiler can't decide that for you. Maybe you can elaborate on **why** you think the first example should work. – Dean Seo Jul 14 '21 at 11:50
  • I thought vector<> would be able to store any type of variable like v.push_back(int); v.push_back(float); (apparently, this isnt how it works...) – SHOOTERNOOB Jul 14 '21 at 13:32

2 Answers2

4

You must make your function template to accept more than one type:

template <typename T>
void print(vector<T> v) {
    return;
}

If you are coming from another language (I think Java uses the syntax you proposed?), I suggest getting a good C++ book to learn from. It's going to be much less painful to learn properly from start than trying to apply your knowledge from other languages in C++.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • `vector<>` would be ok, if there was a default, but there isnt, right? Maybe worth mentioning that. – 463035818_is_not_an_ai Jul 14 '21 at 11:59
  • Gonna do that, thank you. I just had the wrong thought, that vectors could store different datatypes in one Variable... – SHOOTERNOOB Jul 14 '21 at 13:34
  • No, `vector<>` would not be ok even if there was a default. It would not raise an error, but it also wouldn't do what the OP intended, namely implement a generic function. Instead, the function would only work for the default vector. – Christoph Lipka Jul 15 '21 at 00:30
  • @ChristophLipka op coming from Java is just a guess. I just mentioned it because the answer talks about syntax, but syntax wise `some_template<>` can be ok also in C++. Nevermind, maybe my comment was not clear. – 463035818_is_not_an_ai Jul 15 '21 at 08:02
0

If you need to store elements of different types, you should look into polymorphism and class hierarchies. For example, if you had two different classes A and B, and needed a vector to hold either of those, you could make sure that they share a common base class. You could then store pointers or references to such objects in one and the same vector, like so (using smart pointers in this case):

#include <iostream>
#include <memory>
#include <vector>

class Base {
  public:
    virtual ~Base() {}
    virtual void print() = 0;
};
using BasePtr = std::shared_ptr<Base>;

class A : public Base {
  public:
    virtual void print() override { std::cout << "I'm an A" << std::endl; }
};
class B : public Base {
  public:
    virtual void print() override { std::cout << "I'm a B" << std::endl; }
};

void print(const std::vector<BasePtr>& v) {
  for (auto&& i : v)
    i->print();
}

int main()
{
  std::vector<BasePtr> v;
  v.push_back(std::make_shared<A>()); /* create and add an element of type A */
  v.push_back(std::make_shared<B>()); /* create and add an element of type B */
  print(v);
}

(Also, note that I'm passing the vector type as const reference, otherwise it would be copied before being passed into the function.)

Christoph Lipka
  • 652
  • 4
  • 15