C++模板类中的非专用成员
C++ non-specialized member in template class
我有一个关于模板类的问题。例如,参加这个类
template<class TBase> class CTemplateInherit : public TBase
{
public:
virtual void DoNonSpecializedWork();
virtual void DoTemplateWork();
virtual ~CTemplateInherit();
};
// In header file
template<class TBase>
bool CTemplateInherit<TBase>::DoTemplateWork()
{
std::wcout << L"CTemplateInherit::DoTemplateWork" << std::endl;
TBase::DoWork();
return true;
}
// In CPP file
bool CTemplateInherit::DoNonSpecializedWork()
{
std::wcout << L"CTemplateInherit::DoNonSpecializedWork" << std::endl;
return true;
}
现在,我希望能够使用 dllexport 在 CPP 文件中定义非专用方法,并且只将专用化保留在标头中。通常,我想我可以将成员方法定义为模板化,但由于我从 TBase 继承,这是不可能的。
那么我怎么能把它分开呢?我只覆盖 TBase 中的 4 个方法,并希望能够将其他 40 个左右的方法保留为 DLL 中的 DLLEXPORT,而专用化在头文件中。
提前感谢您的建议!
我不太确定您要完成什么,但是在使用模板时,您需要确保根据需要实例化这些模板。将模板定义放在标头中时,可以从编译器获取隐式实例化:每当它看到使用了函数模板并且此模板的定义可见时,它就会实例化该模板。当您将模板放在其他位置时,编译器在需要时不会看到模板定义,因此不会隐式实例化它。但是,您可以自己实例化相应的函数模板,例如:
// In CPP file
template <class TBase>
bool CTemplateInherit<TBase>::DoNonSpecializedWork()
{
std::wcout << L"CTemplateInherit::DoNonSpecializedWork" << std::endl;
return true;
}
template bool CTemplateInherit<SomeBase>::DoNotSpecializeWork();
template bool CTemplateInherit<SomeOtherBase>::DoNotSpecializeWork();
如果您不想更改hierarchy
类。
1( specialize
.cpp
文件中所有需要的类型。
template<>
bool CTemplateInherit<First>::DoNonSpecializedWork()
{
std::wcout << L"CTemplateInherit::DoNonSpecializedWork" << std::endl;
return true;
}
template<>
bool CTemplateInherit<Second>::DoNonSpecializedWork()
{
std::wcout << L"CTemplateInherit::DoNonSpecializedWork" << std::endl;
return true;
}
template<>
bool CTemplateInherit<Nth>::DoNonSpecializedWork()
{
std::wcout << L"CTemplateInherit::DoNonSpecializedWork" << std::endl;
return true;
}
2( 使用
template<typename T>
bool CTemplateInherit<T>::DoNonSpecializedWork()
{
std::wcout << L"CTemplateInherit::DoNonSpecializedWork" << std::endl;
return true;
}
.cpp
文件中,但在header
中使用类似的东西
template class CTemplateInherit<First>;
template class CTemplateInherit<Second>;
template class CTemplateInherit<Nth>;
3(正如迪特马尔所建议的那样。
我认为缺少一条重要信息:非专用方法是否覆盖了TBase
类的虚拟方法?这是这里的核心问题。
如果没有,那么您可以为非专用方法创建另一个类,并从CTemplateInherit
类中的两个类继承(公开(。 问题解决了。
但是,如果非专用方法覆盖了 TBase 类的虚拟方法,则它只是稍微复杂一些:
解决方案 1(获取所有非专用函数并将它们重新分组到一个"详细信息"标头中。要么作为一组(非模板(自由函数(如果很容易将输入输出作为参数传递(,要么作为具有它所需的非专用数据成员的(非模板(类。然后,在相应的 cpp 文件(稍后将编译为 DLL(中定义所有这些函数(实现它们(。
然后,在CTemplateInherit
类模板中,只需将非专用函数调用转发到"detail"函数集即可。由于模板默认为内联,因此开销将为零。如果您需要将"detail"函数重新分组到一个类(非模板(中,那么只需使用private
继承,防止函数名称冲突。然后,您可以像任何其他继承的数据成员一样访问"detail"类的数据成员,并且可以将非专用函数调用转发到"detail"类实现,您可以将其编译为 DLL(如果您有合适的框架用于从 DLL 导出类(因为普通C++没有可靠的机制(, 但你的问题似乎暗示你这样做(。
此解决方案的唯一问题是烦人地创建了几个简单的转发功能。但恕我直言,这是将实现隐藏在 DLL 中的合理代价(几乎任何时候你想这样做,你最终都会编写一堆包装函数(。
解决方案 2(如果基类中有一组非专用的虚函数,那么该子集肯定不依赖于TBase
的实际类型(我的意思是,这些函数的原型可以在没有它的情况下形成(。然后,这意味着您可以将该函数子集重新分组到另一个基类中,TBase
应该从该基类继承。我们称之为TNonSpecialBase
.此时,您可以设置以下层次结构:
class TNonSpecialBase {
// set of pure-virtual functions that are not special.
};
// this is an example of a class that could act as a TBase:
class TExampleBase : public virtual TNonSpecialBase {
// set of virtual functions that are special to TExampleBase.
};
class CNonSpecialDerived : public virtual TNonSpecialBase {
// declaration of non-specialized functions that override the function in TNonSpecialBase.
};
template <typename TBase>
class CTemplateInherit : public TBase, public CNonSpecialDerived {
// set of virtual functions that are specialized for the template argument TBase.
};
通过上述设置,专用函数必须最终位于 CTemplateInherit
的头文件中,但重新分组的非专用函数CNonSpecialDerived
可以在单独的 cpp 文件中定义(并编译为 DLL(。这里的魔术技巧是使用虚拟继承来允许最终类具有基类TNonSpecialBase
的单个虚拟表。换句话说,这允许类CNonSpecialDerived
覆盖TBase中从TNonSpecialBase
继承的虚函数,只要TBase不覆盖任何这些函数(在这种情况下,编译器会称其为歧义(。这样,用户可以处理指向TBase
对象的指针,调用其任何虚拟函数,这将导致向CTemplateInherit
实现(专用(或CNonSpecialDerived
实现(大概在 DLL 中(调度。
- 静态数据成员模板专用化的实例化点在哪里
- 成员变量如何使用专用类模板?
- GCC 7 中模板类的模板成员函数的专用化
- C++ 类模板部分专用化,而不专用化所有成员函数
- 专用于可变参数模板成员函数
- 对专用模板成员的未定义引用
- 对类模板成员的显式专用化的约束
- 具有专用成员函数的默认模板参数
- 如何正确地显式实例化具有完全专用成员的模板类
- C++模板类中的非专用成员
- 运算符<<重载时无法访问专用成员(指定指针)
- 避免强制转换以访问派生类的专用成员
- 枚举类型参数的专用成员模板
- 组织专用成员 Vector<Vector 接口的最佳方式<Type>>
- 基于基类的专用成员函数
- C++模板:专用成员函数,用于解决主模板中不明确的重载情况
- 导出/定义静态模板专用成员变量C++
- 无法访问QXmlStreamReader的专用成员(运算符=)
- 类专用成员-数组访问失败
- C++中非模板类的专用成员函数