如果我使用
等模板定义一个类template<class K, class V>
class myclass {
...
};
有没有办法将myclass定义的对象传递给函数而不使用函数模板?换句话说,对于接受myclass对象的每个函数,它还需要使用模板&lt; K类,V类&gt; ?
这样做的主要原因是我想定义一组作用于myclass对象的静态函数,这样我就可以在cpp文件中而不是在头文件中限制这些函数的范围。
答案 0 :(得分:7)
让你的模板类继承一些基类:
template<class K, class V>
class myclass : mybaseclass { ... };
其中基类将模板的公共功能声明为纯虚拟。这样,每个K
,V
组合只有一个函数而不是一个函数。
答案 1 :(得分:5)
也许你可以运行某种类型的擦除方案,你有一个容器类,它包含一个抽象的成员指针,并为每个类型实例化一个具体的派生对象。 (看看Boost.any。)
有点像这样:
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>();
}
};
现在您可以让您的函数接受MyClass
,但您必须向MyClassHolder
添加足够的虚拟函数,在MyClassConcrete
中实现它们并在MyClass
中公开它们你可以实现所有你想要的语义。
答案 2 :(得分:2)
不,你必须使这些函数也被模板化(除非他们当然只限于使用myclass
的特定专业)。
答案 3 :(得分:2)
你可以这样做:
void myfunc(const myclass<int, int>& mc) {}
只有当您希望能够将任何类型传递给函数中的myclass
参数时,您是否也需要将myfunc
设为模板。
答案 4 :(得分:2)
是的,如果您希望您的函数能够接受模板类的任何实例化,那么它们也必须是模板(通常使用与该类相同的模板参数)。
另一方面,您可以让模板类继承自非模板类,该模板类仍允许您通过虚函数操作派生类。另外,要隐藏类的类型并避免使用template
的所有代码,可以使用type erasure的几种技术。
答案 5 :(得分:1)
由于C ++的静态特性,您必须为源中的每个(K,V)对实例化该函数的副本,因为编译器必须生成代码以不同方式访问每个对的成员。
答案 6 :(得分:1)
虽然我的理由并不完全清楚,是的,每个以myclass作为参数的函数也必须在K和V上进行模板化。如果你设法抽象基础知识,你可以拥有每个{{1 (对于K和V的每个组合,它是不同的类型)从实现该功能的单个基类继承,或者通过虚函数转发它。