[英]Building a variadic template class with a set of function overloads based on the template arguments?
动机:我需要为 C++17 库构建一个基类,该基类将根据用户在编译时识别的类型对虚函数进行重载。 基本上,当在基类上调用函数的特定重载时,我想确保在派生类中调用正确的版本。 我最初的直觉是构建一个虚模板函数,但当然 C++ 不允许这样做,因为编译器不知道将它的哪个版本放入虚函数表中。 但是,由于我将在编译时知道所有类型,是否可以使基类本身成为可变参数模板并使用模板参数来构建所需的虚函数的重载版本集?
折叠表达式是正确的,因为它们不能用于声明函数。 递归模板看起来很有前途,但我担心基类的长继承链会影响性能。 这是我拥有的工作代码:
template <typename... Ts> class MyClass;
template <typename T, typename... Ts>
struct MyClass<T, Ts...> : public MyClass<Ts...> {
using MyClass<Ts...>::MyFunction;
virtual bool MyFunction(T in) { return true; }
};
template <>
struct MyClass<> {
virtual bool MyFunction(...) { return false; }
};
这种技术应该足够了吗? 或者有人对我如何实现这个目标有其他想法吗?
我的其他想法包括:
限制可以处理和启用的模板参数的数量 - 如果每个重载基于参数列表是否足够长以包含它。 缺点:这种技术将是对类型数量的任意限制。
使用可变参数宏来构建类。 缺点:这种技术会令人困惑和不雅。
创建一个函数,为基类中的 ID 编号分配类型,将其作为带有其 ID 的void *
传递给派生类,然后在该点将其转换回以进行适当的重载调用。 缺点:这种技术很难保证类型安全并最大限度地减少最终用户需要做的工作量。
现在,我倾向于实施这些替代方案中的第一个,并进行一些性能测试以将其与我的工作版本进行比较,但是如果我缺少一些更清洁的东西,我会很高兴。
您的实现适用于 C++14。
C++17 允许using
可变参数,以避免递归:
template <typename T>
struct MyClassImpl
{
virtual ~MyClassImpl() = default;
virtual bool MyFunction(T in) = 0; // or { return true; }
};
template <typename... Ts>
struct MyClass : public MyClassImpl<Ts>...
{
using MyClassImpl<Ts>::MyFunction...;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.