【问题标题】:Is it possible to define a non-template function that can take a templated object as a parameter是否可以定义一个可以将模板化对象作为参数的非模板函数
【发布时间】:2019-07-10 10:38:02
【问题描述】:

我正在使用模板化的 C++ 类。

我实例化了这个类的两个不同的模板化版本:

ExampleClass<ParamType1> obj1;
ExampleClass<ParamType2> obj2;

这样我就有了两个对象,它们是同一个类,但具有不同的模板参数。

我现在希望能够定义一个可以将 obj1 或 obj2 作为参数的函数(极其简化的示例!):

int func(ExampleClassXXX obj_param)
{
  return obj_param.member_operation();
}

这样我就可以打电话给func(obj1)func(obj2

这是可能的吗?如果是,函数定义指定obj_param参数所需的语法是“使用任何模板参数创建的ExampleClass的实例”?

this question 的答案涵盖了更普遍的情况——“obj_param”是任何类型。该答案的文本中缺少大部分细节,只有当您单击“实时演示”时,您才会看到他们正在实例化一个模板化的struct 以便能够传入通用参数,这非常难看.

这似乎应该是一件常见的事情,但谷歌搜索到目前为止让我失败(搜索“将模板化对象作为函数参数传递”)

【问题讨论】:

  • “所以我有两个对象,它们是同一个类,但具有不同的模板参数。” - obj1obj2 是不同的、不相关的类的对象. func 也需要是模板,例如 template&lt;typename x_Param&gt; int func(ExampleClass&lt;x_Param&gt; obj_param)
  • 使函数成为模板函数,或者声明一个基类并将其作为参数
  • ExampleClass 是模板,ExampleClass&lt;ParamType1&gt; 是类。

标签: c++ templates


【解决方案1】:

注意

ExampleClass<ParamType1>

ExampleClass<ParamType2>

基本上是两种不同的语言类。

在我看来,你有两种可能,第一种是:

template<typename ParamType>
int func(ExampleClass<ParamType> obj_param){}

第二种可能性是像这样给ExampleClass一个非模板化的公共基类(基本上实现类型擦除)

 template<typename T>
 class ExampleClass : public ExampleClassBase{};

然后将函数重写为

int func(ExampleClassBase& obj_param){}

但由于对象切片问题,在这种情况下您将无法按值传递。

模板函数强制你在头文件中实现函数,如果你想保持它尽可能通用,非模板基类强制你为虚函数调用付费。

编辑:根据 Alan Birtles 的评论,如果您已经知道将实例化 ExampleClass 的所有类型,您可以在 cpp 文件中实现该函数的每个版本。

【讨论】:

  • “模板化函数强制你在头文件中实现函数”不一定,你可以在cpp文件中提供每个类的实现,只需在头文件中声明函数
  • @AlanBirtles 我不确定是否将其添加到描述中,这是一个好点,但我觉得它可能提供了太多信息。我会更新答案。
【解决方案2】:

这样我就有了两个对象,它们是同一个类,但具有不同的模板参数。

那里有矛盾。如果论点不同,则这不是同一个类。模板不是一个类,它是一个模具。如果你将两种不同的金属倒入其中,你会得到两个非常不同的物体,尽管形状相似。它们具有不同的质量和密度,可能具有不同的电磁特性,等等。有点切题,但重要的是要区分模板与其产生的东西,它们是不一样的。

这就是为什么从同一个模板产生的不同专业化被认为是不同的类。它们在类型系统下不相关,因此没有任何函数可以自动将它们视为同一事物。您可以创建一个函数模板,并使用它为每个不同的专业化生成函数,但它们也将是不同的函数。

如果您有一个对所有专业都通用的部分,您可以将其重构为一个基类(正确的类,而不是类模板),并拥有一个接受 的函数。 p>

【讨论】:

  • 虽然正确,但您的回答并没有真正回答 OP 的问题。我理解 OP 存在矛盾,但根本问题很清楚。
  • @Neijwiert - 我可以发誓我在最后写了一点关于公共基类的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-06
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多