- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个类模板 Function
,它接受一个无符号整数作为模板参数,用于输入的数量。此模板重载 operator()
,因此可以针对一组给定的输入评估 Function
。
通常,该成员的原型(prototype)之一是operator()(double, ...)
。但是,如果模板参数为 0,则该原型(prototype)将不起作用,因为它至少需要一个参数。
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 operators 来处理 Arity
等于 0:
#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);
}
关于c++ - 仅更改一个成员函数的类模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41514405/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!