只更改一个成员函数的类模板专用化
Class template specialization that changes only one member function
我有一个类模板Function
,它将一个无符号整数作为输入数的模板参数。该模板重载operator()
,因此可以针对一组给定的输入来评估Function
。
通常,该成员的原型之一是operator()(double, ...)
。但是,如果模板参数为0,则该原型将不起作用,因为它至少需要一个参数。
template <unsigned Arity>
struct Function {
void operator () (double, ...);
};
通常,我只会编写一个模板专用化,但会有很多冗余代码,因为还有很多其他成员函数。同样,通常情况下,我会创建一个基类,其中包含主类定义和要继承的专门化的冗余代码。
struct FunctionBase {
// Common code
Function operator + (Function const &) const; // ?
};
template <unsigned Arity>
struct Function : FunctionBase { /* etc */ };
不幸的是,我不确定如何执行此操作,因为例如operator+
意味着返回Function
。但是,如果以后才定义Function
,它怎么能做到这一点呢?Function
继承了基类,通过这种设计,operator+
在基类中。。。
它可以返回基类的一个实例,但我们需要一种方法将该实例转换为Function
的实例,我知道如果不复制第一个实例的数据,就无法做到这一点,这在性能方面非常昂贵。
我怎样才能做到这一点?
这个问题很难回答,因为它还很不清楚
以下两种可能的解决方案:
-
如果你想继续使用
Arity
模板参数,你可以使用sfinae'd运算符来处理等于0:的Arity
#include<iostream> template<int Arity> struct Function { template<int N = Arity> std::enable_if_t<N == 0> operator()() { std::cout << "arity == 0" << std::endl; } template<int N = Arity> std::enable_if_t<N != 0> operator()(double, ...) { std::cout << "arity != 0" << std::endl; } }; int main() { Function<0> f1; Function<2> f2; f1(); f2(0., 42); }
这样,您就不再需要引入基类,所有相关的问题也不再适用。
-
如果你介意改变方法,你可以为你的函数对象切换到以下模式:
template<typename> struct Function; template<typename R, typename... A> struct Function<R(A...)> { R operator()(A... args) { // ... } // ... };
您可以按如下方式使用它:
Function<void(int, char)> f;
如果你想有一个固定的
double
作为operator()
的第一个参数,你可以这样做:template<typename R, typename... A> struct Function<R(double, A...)> { R operator()(double d, A... args) { // ... } // ... };
并按如下方式使用:
Function<void(double, int, char)> f1; Function<void(double)> f1;
这将至少有助于轻松处理空参数包(注意,
sizeof...(A)
在任何情况下都会向您返回提交的参数数量)。它遵循一个最小的工作示例实现:
#include<iostream> template<typename> struct Function; template<typename R, typename... A> struct Function<R(A...)> { R operator()(A... args) { int _[] = { 0, (std::cout << args << std::endl, 0)... }; (void)_; } template<typename... O> Function<R(A..., O...)> operator+(Function<R(O...)>) { return {}; } // ... }; int main() { Function<void(int)> f1; Function<void(double)> f2; f1(42); f2(0.); (f1+f2)(3, .3); }
相关文章:
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 使用 C++20 概念模板函数专用化时的依赖项
- 将 c++ 类成员函数专用于模板类
- 使用模板模板参数进行模板定义的函数专用化
- 返回值的简单模板类成员函数专用化
- 已专用类的成员函数专用化
- 部分模板函数专用化enable_if:默认实现
- 使用数组参数进行函数专用化
- 模板函数专用化的内部编译器错误
- 在子类中定义可变参数函数专用化
- 使用模板的构造函数专用化
- 模板函数专用化Enable_if
- 如何将模板构造函数专用化移动到 cpp 文件
- 模板类模板构造函数专用化
- 模板类是否可以用作模板函数专用化的参数
- 未调用数组的函数专用化
- 如何将模板成员函数专用化为另一个模板类
- 模板类的模板函数专用化
- 参数值的自动模板函数专用化
- 如何在类中使用成员函数专用化