gpt4 book ai didi

c++ - 如何将函数应用于数组中的所有元素(在 C++ 模板类中)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:34:17 49 4
gpt4 key购买 nike

我有一个存储数字数组的模板类,我想将现有(标量)函数应用于每个元素。例如,如果我们假设我的类是 std::vector,那么我希望能够在所有元素上调用(例如)std::cos 函数。

也许一个电话看起来像这样:

std::vector<float> A(3, 0.1f);
std::vector<float> B = vector_function(std::cos, A);

注意我还必须处理 std::complex<> 类型(为此调用适当的复杂 std::cos 函数)。

我找到了 this answer这建议将函数类型作为模板参数:

template<typename T, typename F>
std::vector<T> vector_function(F func, std::vector<T> x)

但是,我根本无法让它工作(可能是因为像 std::sin 和 std::cos 这样的函数都是模板化和重载的?)。

我也尝试过使用 std::transform,但这很快就变得非常难看。对于非复杂类型,我设法使用 typedef 让它工作:

std::vector<float> A(2, -1.23f);
typedef float (*func_ptr)(float);
std::transform(A.begin(), A.end(), A.begin(), (func_ptr) std::abs);

但是,尝试对 std::complex<> 类型使用相同的技巧会导致运行时崩溃。

有什么好的方法可以让它正常工作吗?我多年来一直坚持这一点。

最佳答案

我仍然认为你应该使用 std::transform:

template <class OutputIter, class UnaryFunction>
void apply_pointwise(OutputIter first, OutputIter last, UnaryFunction f)
{
std::transform(first, last, first, f);
}

此函数不仅适用于 std::vector 类型,而且实际上适用于任何具有 begin()end() 成员的容器函数,它甚至可以在免费函数 std::beginstd::end 的帮助下用于 C 风格的数组。一元函数可以是任何自由函数、仿函数对象、lambda 表达式甚至类的成员函数。

至于 std::sin 的问题,这个自由函数是模板化的,因此编译器无法知道您需要哪个模板实例化。

如果您可以访问 C++11,则只需使用 lambda 表达式:

std::vector<float> v;
// ...
apply_pointwise(v.begin(), v.end(), [](const float f)
{
return std::sin(f);
});

这样,编译器就知道它应该将 T=float 替换为模板参数。

如果你可以使用 C 函数,你也可以使用 sinf 函数,它不是模板化的并且以一个 float 作为参数:

apply_pointwise(v.begin(), v.end(), sinf);

关于c++ - 如何将函数应用于数组中的所有元素(在 C++ 模板类中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29468693/

49 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com