如何概括作用于不同类型向量的函数?

How to generalize the functions, which acting on a vector of different types?

我是 C++ 的新手,我似乎无法正确表述我的问题。由于 vectorize 和 map 的含义似乎与我正在寻找的不同(因此很难通过谷歌搜索解决方案)。

我有很多作用于任意类型的单个对象的函数。我想要一种通用方法(即模板或包装函数)将它们转换为作用于任意数量的相同类型对象的向量的函数。

一个例子:

int func1(int a) {return a+1;}
long func2(long a) {return a*10;}

vector<int> func1(vector<int> a_vec)
{
    vector<int> out_vec;
    for (int i = 0; i < a_vec.size(); i++)
        out_vec.push_back(func1(a_vec[i]));
    return out_vec;
}

vector<long> func2(vector<long> a_vec)
{
    vector<long> out_vec;
    for (int i = 0; i < a_vec.size(); i++)
        out_vec.push_back(func2(a_vec[i]));
    return out_vec;
}

模板似乎是必需的,但我对它们还没有太多经验,也不知道如何在这种情况下应用它们。任何 references/suggestions/comments 欢迎。

(另外请添加相关标签 - 因为我不确定正确的术语,所以我不确定如何标记它)。

此代码确实看起来非常适合某些模板。

template <typename T, typename TFunc>
std::vector<T> transform(const std::vector<T> &v, TFunc &&func)
{
    std::vector<T> result;
    result.reserve(v.size());
    for (auto &&element : v)
        result.push_back(std::invoke(func, element));
    return result;
}

您可能会注意到该函数看起来与 std::transform 非常相似,后者适用于迭代器而不是向量。它可以被称为:

 auto result = transform(v, &func1);

是的,您将需要模板,因为您不知道将使用此矢量化函数的类型。

让我们试试看:

#include <vector>
#include <iostream>

int func1(int i){ return i + 1; }

template<typename valueT, typename callableT>
std::vector<valueT> vectorize(const std::vector<valueT>& input, callableT funcToCall)
{
    std::vector<valueT> result;
    for (auto& x : input) result.push_back(funcToCall(x));
    return result;
}


int main()
{
    std::vector<int> iVector{2,3,5,7,11,13,17};

    std::vector<int> output = vectorize(iVector, &func1);

    for (const auto& x : output) std::cout << x << std::endl;

    return 0;
}

正如评论中提到的@paler123,你可以使用std::transform来完成这项工作+一个小的模板化功能。

因为你的两个函数在函数签名上有相似之处

i.e, Type function(Type arg)

我选择了类型函数指针作为模板函数参数。

template<typename Type>
std::vector<Type> func(const std::vector<Type>& a_vec, Type(*func)(Type))
{
    std::vector<Type> out_vec; out_vec.reserve(a_vec.size());
    std::transform(a_vec.begin(), a_vec.end(), std::back_inserter(out_vec), func);
    return out_vec;
}

现在在 main() 中,您可以显式指定类型或保留原样,让编译器进行类型推导。

auto result = func<int>({ 1,2,3,4 }, func1);
// also can
auto result2 = func({ 1, 2, 3, 4 }, func2);

sample output here