You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将任意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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:15:04