一般采用可索引/可调用的线性组合
Generically taking linear combinations of indexibles/callables
我正在尝试全局扩展并将可调用/可索引对象(抽象数学意义上的向量(相加。
也就是说,我正在尝试采用定义operator[]
或operator()
的对象线性组合。
例如,我希望能够做到这一点:
LinearCombination<std::function<double(double, double)>> A([](double x, double y){
return 1+x+std::pow(x,2)+std::sin(y);
});
LinearCombination<std::function<double(double, double)>> B([](double x, double y){
return 1-x+std::cos(y);
});
A*= 2.5;
A += B;
std::cout << A(1.0,2.0) << std::endl;
<小时 />我的尝试
// ZERO ///////////////////////////////////////////////////////////////////////////////////////////
namespace hidden {
// tag dispatching: from https://stackoverflow.com/a/60248176/827280
template<int r>
struct rank : rank<r - 1> {};
template<>
struct rank<0> {};
template<typename T>
auto zero(rank<2>) -> decltype(static_cast<T>(0)) {
return static_cast<T>(0);
}
template<typename T>
auto zero(rank<1>) -> decltype(T::zero()) {
return T::zero();
}
template<typename T>
auto zero(rank<0>)->std::enable_if_t<
std::is_assignable<std::function<double(double,double)>, T>::value
, std::function<double(double,double)>> {
return []() {
return 0.0;
};
}
}
template<typename T>
auto zero() { return hidden::zero<T>(hidden::rank<10>{}); }
// LINEAR COMBINATION ///////////////////////////////////////////////////////////////////////////////////////////
template<typename V, typename C = double>
struct LinearCombination {
struct Term {
C coeff;
V vector;
// if V(x...) is defined
template<typename ...X>
auto operator()(X&&... x) const -> std::remove_reference_t<decltype(std::declval<V>()(std::forward<X>(x)...))> {
return vector(std::forward<X>(x)...) * coeff;
}
// if V[i] is defined
template<typename I>
auto operator[](I i) const -> std::remove_reference_t<decltype(std::declval<V>()[i])> {
return vector[i] * coeff;
}
};
std::vector<Term> terms;
LinearCombination() {} // zero
/*implicit*/ LinearCombination(V&& v) {
terms.push_back({ static_cast<C>(1), std::move(v) });
}
/*implicit*/ LinearCombination(Term&& term) {
terms.push_back(std::move(term));
}
LinearCombination<V, C>& operator+=(LinearCombination<V, C>&& other) {
terms.reserve(terms.size() + other.terms.size());
std::move(std::begin(other.terms), std::end(other.terms), std::back_inserter(terms));
other.terms.clear();
return *this;
}
LinearCombination<V, C>& operator*=(C multiplier) {
for (auto& term : terms) {
term.coeff *= multiplier;
}
return *this;
}
// if V(x...) is defined
template<typename ...X>
auto operator()(X&&... x) const
-> std::remove_reference_t<decltype(std::declval<V>()(std::forward<X>(x)...))> {
auto result = zeroVector()(std::forward<X>(x)...); <--------------- *** BAD FUNCTION CALL ***
*************************
for (const auto& term : terms) {
result += term(std::forward<X>(x)...);
}
return result;
}
// if V[i] is defined
template<typename I>
auto operator[](I i) const -> std::remove_reference_t<decltype(std::declval<V>()[i])> {
auto result = zeroVector()[i];
for (const auto& term : terms) {
result += term[i];
}
return result;
}
private:
static const V& zeroVector() {
static V z = zero<V>();
return z;
}
};
这对我来说编译得很好,但我在指示的行上得到了一个异常(错误的函数调用(。你能帮忙吗?
此函数:
template<typename T>
auto zero(rank<2>) -> decltype(static_cast<T>(0));
在以下方面赢得重载解决方案:
template<typename T>
auto zero(rank<0>)->std::enable_if_t<
std::is_assignable<std::function<double(double,double)>, T>::value
, std::function<double(double,double)>>;
这是因为rank<2>
比rank<0>
更适合rank<10>{}
,而且:
static_cast<std::function<double(double,double)>>(0)
是一个有效的表达式。
也就是说,std::function
具有以下构造函数:
function(std::nullptr_t) noexcept;
这使得它成为0
参数的可行选择,并且static_cast
确实考虑了构造函数。
您最终会得到使用0
(空(初始化std::function<double(double,double)>
,这会导致您尝试调用它时出现异常。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 一般采用可索引/可调用的线性组合
- 为什么排序调用比较函数的频率低于线性最小搜索算法
- 关于修复对向量的线性搜索函数的调用的建议