C++:调用模板化类的非模板化函数

C++: call non-templated functions of a templated class

本文关键字:函数 C++ 调用      更新时间:2023-10-16

在模板化的类中有可能拥有可调用的、非模板化的函数吗?像这样:

template<typename T>
class Object
{
public:
  static int loadInfo() { return 0;}
  // more code
};

我想写,例如:

Object::loadInfo();

而不是

Object<int8_t>::loadInfo();

它实际上并不重要,只是一些"句法糖"。更多的背景知识:我正在考虑的函数将从磁盘加载一些数据,程序在这些数据上决定必须使用对象的模板版本。ATM它看起来像这样:

auto usewhat=Object<char>::loadInfo();   // this line feels so wrong
if(usewhat == 0) {
  Object<int8_t> o;
  o.doSomething();
}else if(usewhat == 1){
  Object<int32_t> o;
  o.doSomething();
}else{
  Object<int64_t> o;
  o.doSomething();
}

我能想到的atm的唯一可能性是1)使用不同名称的非模板基类(比如"BaseObject")或2)使用另一个不同名称的类(比如"InfoObject")。。。但这两种可能性似乎都不太吸引人。

您应该使loadInfo成为一个自由函数(可能使用不同的名称,如loadObjectInfo或任何有意义的名称来指示与Object的语义关系)。

尽管它是一个static函数,不依赖于Object的特定实例,但它仍然依赖于Object的模板参数:该函数可能使用T,尽管在您的情况下它显然没有。这意味着编译器将为每个具有不同TObject<T>::loadInfo生成新代码,这意味着构建速度较慢,可能会生成更大的二进制文件。此外,您不能在cpp文件中实现该函数。

如果您有Scott Meyers的Effective C++(第三版)的副本,您可能需要查找第44项("模板外的因子参数独立代码")。

不能直接使用,但可以使用typedef:

typdef Object<int8_t> MyObject;
MyObject::loadInfo();

如果函数可以从类中移出,就执行它。

如果它不能移出类,但不依赖于T,则说明你的类太胖,应该拆分。

class ObjectBase {
  // stuff that doesn't depend on T
  static int loadInfo();
};
template <typename T>
class Object : public ObjectBase {
  // more stuff
};

实际上,我认为没有可移植的方法可以在不指定模板的情况下调用模板类的函数。我还建议尽可能保持代码的可移植性,因为它可能会在未来对您有所帮助(使用的其他编译器和您当前使用的另一个版本的编译器)。