c ++将向量的内容作为参数传递给函数

时间:2014-03-21 09:58:03

标签: python c++

在python中我们可以这样做:

def test(a, b, c):
    return a+b+c

x = [1, 2, 3]
y = test(*x)

我们可以在C ++中做类似的事情吗?

5 个答案:

答案 0 :(得分:2)

到目前为止提出的解决方案基于对函数参数的运行时迭代,这会产生一些成本。他们还假设参数类型是相同的。如果参数的数量在编译时是已知的(通常是),则不同的解决方案就像

template <typename F, typename T>
auto tuple_call3(F&& f, const T& t)
-> decltype(std::forward<F>(f)(std::get<0>(t), std::get<1>(t), std::get<2>(t)))
   { return std::forward<F>(f)(std::get<0>(t), std::get<1>(t), std::get<2>(t)); }

struct test
{
   template <typename A, typename B, typename C>
   auto operator()(const A& a, const B& b, const C& c)
   -> decltype(a + b + c)
      { return a + b + c; }
};

int main()
{
    auto x = std::make_tuple(1, 2, 3);
    auto y = tuple_call3(test(), x);
    cout << y << endl;
}

没有运行时成本并且使用异构参数类型。我现在没有时间进一步开发这个,但为了使它完全通用,我们需要

  • 在任何地方使用通用引用(如F&&)和转发(如std::forward<F>(f)),当然包括函数参数。

  • 使tuple_call变量。为此,如果L是元组的大小(通过tuple_size),我们需要在编译时生成序列0,...,L-1(参见例如函数range {{3 }})。如果N...是此序列,请使用std::get<N>(t)...

  • 使用普通功能。现在test是一个函数对象,也可以是一个lambda,但是一个普通函数应该不是模板,或者明确指定其模板参数(在tuple_call上);否则无法推断其类型F

如果所有这些都集成在C ++语言中,那就太好了,但它还没有。至少有工具可以制作大致相同的东西。顺便说一句,我不知道Python中等效的运行时成本是多少。

答案 1 :(得分:1)

至少,我认为下面的代码接近你的python代码

int test(const std::vector<int>& v)
{
    return std::accumulate(v.begin(), v.end(), 0);
}

std::vector<int> x = { 1, 2, 3 };
int y = test(x); 

答案 2 :(得分:1)

是的,你可以。例如

#include <numeric>
#include <initializer_list>

int test( std::initializer_list<int> l )
{
    return std::accumulate( l.begin(), l.end(), 0 );
}

int y = test( { 1, 2, 3 } );

或者

int test( const int a[] )
{
    return a[0] + a[1] + a[2];
}

int a[] = { 1, 2, 3 };
int y = test( a );

或者

#include <vector>
#include <numeric>
int test( const std::vector<int> &v )
{
    return std::accumulate( v.begin(), v.end(), 0 );
    // or return v[0] + v[1] + v[2];
}

std::vector<int> v = { 1, 2, 3 };
int y = test( v );

答案 3 :(得分:0)

不,没有单行将容器转换为函数的必需参数。这是因为在C ++中,函数调用是在编译期间处理的,而容器的内容在运行时是已知的。

所以我最接近的例子是

int test(int a, int b, int c) { return a + b + c; }

std::vector<int> x = { 1, 2, 3 };
int y = test(x[0], x[1], x[2]);

请注意,由于您必须在python中注意容器中的元素数量与预期的参数匹配,因此给定的示例不是很有用。

答案 4 :(得分:0)

是的,如果您正在谈论将文字转换为类似矢量的对象,请参阅std::initializer_list(C ++ 11)

template <typename T>
void test(std::initializer_list<T> aList) {
    //do stuff with aList, for example std::accumulate,
    //or make a vector with it: std::vector<T> v(aList);
}

auto x = {10, 11, 12};
test(x)

但是如果你需要使用一个具有&#34; normal&#34;参数,你需要用va_args微动,参见va_arg中的例子,所以答案可能是&#34; No&#34;。