Home > database >  How to pass a C Template instance to a function?
How to pass a C Template instance to a function?

Time:11-30

How can I pass any object of an templated class to another function in C 11?

In the snippet below passInObj does not compile because it complains about Printer&. I want to pass in any Printer it does not matter which template T I have used.

How can I do this and why does the solution below not work?

#include <iostream>
#include <vector>
template <typename T>
class Printer {
  public:
   Printer(const T& tl) : t(tl) {}
   void print() const {
     for (auto x : t) {
        std::cout << x << std::endl;
      }
   }
   const T &t;
};

// THIS LINE DOES NOT COMPILE
void passInObj(const Printer& p) {
   p.print();
}

int main() {
  std::vector<std::string> vec;
  vec.push_back("ABC");
  Printer<std::vector<std::string>> printer(vec);
  printer.print();
  passInObj(p);
  return 0;
}

CodePudding user response:

How can I do this

You need to make it into a function template:

template <class T>
void passInObj(const Printer<T>& p) {
    p.print();
}

Demo

and why does the solution below not work?

Because Printer is not a type, it's only a template. For passInObj to work with any Printer<T>, you need to make the function into a function template so that it'll be instantiated for every Printer<T> which is used to call it.

CodePudding user response:

While @TedLyngmo's answer should be your go-to by default, you can also do this via a polymorphic interface if you cannot make passInObj() a template for some reason or other.

This is done by adding a base interface class that will be derived by all Printer<> classes:

#include <iostream>
#include <vector>

class IPrinter {
  public:
    virtual void print() const = 0;

  // Either that or public and virtual
  protected:
    ~IPrinter() = default;
};

template <typename T>
class Printer : public IPrinter {
  public:
   Printer(const T& tl) : t(tl) {}
   void print() const override {
     for (auto x : t) {
        std::cout << x << std::endl;
      }
   }
   const T &t;
};

void passInObj(const IPrinter& p) {
   p.print();
}

int main() {
  std::vector<std::string> vec;
  vec.push_back("ABC");
  Printer<std::vector<std::string>> printer(vec);
  printer.print();
  passInObj(p);
  return 0;
}
  • Related