如何将任意C++模板类实例作为参数传入普通函数
编译失败原因
Printer是模板类,本身仅为类型生成的蓝图,必须指定模板参数才能作为合法类型使用。你在定义passInObj函数时,形参直接写const Printer& p,没有为Printer指定模板实参,编译器无法匹配到任何合法的类型定义,因此直接报编译错误。
另外你的代码存在笔误:main函数中定义的Printer实例变量名为printer,调用passInObj时传的参数是未定义的p,这也是编译报错点之一。
实现方案
方案1:将passInObj定义为模板函数(C++11兼容,零额外开销)
直接把passInObj改为模板函数,编译器会自动推导传入的Printer实例的模板参数,无需手动指定:
template<typename T> void passInObj(const Printer<T>& p) { p.print(); }
该方案没有任何运行时额外开销,所有调用逻辑在编译期即可确定,是最常用的实现方式。
方案2:提取公共非模板基类,使用运行时多态
如果你希望passInObj是普通非模板函数,可以通过抽象基类实现运行时分发:
// 新增非模板抽象基类 class PrinterBase { public: virtual void print() const = 0; virtual ~PrinterBase() = default; }; // Printer类继承基类 template <typename T> class Printer : public PrinterBase { public: Printer(const T& tl) : t(tl) {} // print函数保持原有实现即可 void print() const override { for (auto x : t) { std::cout << x << std::endl; } } private: const T &t; }; // 形参用基类引用,无需模板 void passInObj(const PrinterBase& p) { p.print(); }
该方案的优势是可以把passInObj的声明和实现分离到cpp文件,减少编译依赖,缺点是会产生极小的虚函数调用开销。
完整可运行代码示例(采用方案1)
#include <iostream> #include <vector> #include <string> template <typename T> class Printer { public: Printer(const T& tl) : t(tl) {} void print() const { for (auto x : t) { std::cout << x << std::endl; } } private: const T &t; }; template<typename T> void passInObj(const Printer<T>& p) { p.print(); } int main() { std::vector<std::string> vec; vec.push_back("ABC"); Printer<std::vector<std::string>> printer(vec); printer.print(); passInObj(printer); return 0; }
内容的提问来源于stack exchange,提问作者robert
相关产品推荐
相关产品推荐

