简体   繁体   English

将模板类作为参数传递给函数

[英]Passing a template class as an argument to a function

If I define a class using a template such as 如果我使用模板定义类,例如

template<class K, class V>
class myclass {
...
};

is there a way to pass objects defined by myclass to functions without using a template for the function? 有没有一种方法可以将myclass定义的对象传递给函数,而无需使用该函数的模板? In order words, for every function that accepts myclass objects, does it also need to be defined using template< class K, class V> ? 换句话说,对于每个接受myclass对象的函数,是否还需要使用template <class K,class V>进行定义?

The main reason for this is that I would like define a set of static functions that act on myclass objects so that I may limit the scope of these functions within their cpp files and not in header files. 这样做的主要原因是,我想定义一组作用于myclass对象的静态函数,以便可以将这些函数的范围限制在其cpp文件中,而不是在头文件中。

Make your template class inherit from some base class: 使您的模板类继承自某些基类:

template<class K, class V>
class myclass : mybaseclass { ... };

where the base class declares the public functionality of the template as pure virtual. 基类在其中将模板的公共功能声明为纯虚拟的。 This way you only have one function rather than one function for each K , V combination. 这样,每个KV组合只有一个功能,而没有一个功能。

No, you cannot. 你不能。 A class template is not a class -- it is only a template. 类模板不是类,而只是一个模板。 Only once you plug in the template parameters do you get a type, and for each different set of parameters you get a different , unrelated type. 只有插入模板参数后,您才能获得类型,对于每组不同的参数,您将获得不同的不相关的类型。

Perhaps it's feasible for you to run some sort of type-erasing scheme, whereby you have a single container class which contains an abstract member pointer, and for each type you instantiate a concrete derived object. 也许对您来说,运行某种类型擦除方案是可行的,即您有一个包含抽象成员指针的容器类,并且对于每种类型,您都实例化了一个具体的派生对象。 (Check out Boost.any.) (查看Boost.any。)

A bit like this: 有点像这样:

class MyClassHolder { };

template <typename K, typename V>
class MyClassConcrete {  };

class MyClass
{
  MyClassHolder * p;

public:
  template <typename K, typename V> init(...)  // could be a constructor
  {
    p = new MyClassConcrete<K, V>();
  }
};

Now you can make your function accept a MyClass , but you have to add enough virtual functions to MyClassHolder , implement them in MyClassConcrete and expose them in MyClass that you can realise all your desired semantics. 现在你可以让你的函数接受一个MyClass ,但你必须要足够的虚拟函数添加到MyClassHolder中,实现它们MyClassConcrete ,揭露他们在MyClass ,你可以实现你所有所需的语义。

不,您也必须使函数模板化(当然,除非将它们限制为仅使用myclass的特定专业化)。

You could do this: 您可以这样做:

void myfunc(const myclass<int, int>& mc) {}

Only if you wanted to be able to pass any type to your myclass argument in your function, would you need to make that myfunc a template too. 仅当您希望能够将任何类型传递给函数中的myclass参数时,才需要使该myfunc成为模板。

Yes, if you want your functions to be able to accept any instantiation of your template class they too must be template (typically with the same template parameters that are used for the class). 是的,如果您希望函数能够接受模板类的任何实例化,它们也必须是模板(通常使用与该类使用的模板参数相同)。

On the other hand, you can have your template class inherit from a non-template class that still allows you to operate the derived class via virtual functions. 另一方面,您可以让模板类从非模板类继承而来,该类仍然允许您通过虚拟函数来操作派生类。 Also, to hide the type of your class and avoid riddling all your code of template s, there are the several techniques of type erasure . 另外,要隐藏类的类型并避免使template的所有代码混乱,有几种类型的擦除技术。

由于C ++的静态性质,您必须为源中的每个(K,V)对实例化该函数的副本,因为编译器将不得不生成代码以不同地访问每个对的成员。

尽管我不清楚您的原因,是的,每个将myclass作为参数的函数也必须在K和V上进行模板化。如果设法抽象基础,则可以使每个myclass< K, V > (对于K和V的每种组合,这是不同的类型)(继承自实现该功能的单个基类,或通过虚函数转发)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM