问题 我们可以在即将到来的c ++ 0x标准下通过这种语法将数组作为参数传递给函数吗?


假设我们有以下功能:

void someFunction(int * araye){
 for (int i=0;i<5;i++)
  cout <<araye[i]<<' ';
 cout <<'\n';
}

我们可以在即将到来的c ++ 0x标准下通过以下语法将数组传递给此函数吗? :

someFunction({1,2,3,4,5});

如果这是真的,我们甚至可以在任何情况下使用这种语法,其中数组元素来自POD类型,如下所示:

class Test{
 int adad1;
 int adad2;
};
void someFunction(Test * araye){
 for (int i=0;i<3;i++)
  cout <<araye[i].adad1<<'-'<<araye[i].adad2<<' ';
 cout <<'\n';
}
someFunction({{1,2},{3,4},{5,6}});

编辑 - >之后人们说:
所以你们要告诉大括号之间的表达式基本上会被视为initializer_list,并建议使用一个额外的函数将指针从该initializer_list中拉出来并将其传递给预期的函数,但这种方法在我看来就像是一个hack to能够使用我的预期函数与该表达式作为参数,据说我认为我不应该使用该表达式作为参数,当我的预期函数参数是单个指针,或者可能有另一种方法使用那表达? 。


11685
2017-08-06 14:26


起源

对待时,这将是甜蜜的 int 数组如 char 数组已经永远...... - Mike DeSimone


答案:


如果您的功能需要 const int*, 而不是 int*,那么你只需要一个小蹦床功能来拉出指针 std::initializer_list<int> 支撑初始化器产生的。像这样的东西(可能;我没有要测试的C ++ 0x编译器)

void someFunction(const int * array){
    for (int i=0; i<5; i++)
        std::cout << array[i] << ' ';
    std::cout << '\n';
}

void someFunction(const std::initializer_list<int>& init) {
    someFunction(init.begin());
}

someFunction({1,2,3,4,5});

如果你的函数需要知道数组的结束或大小(通常是这种情况),那么通过它们 init.end() 要么 init.size() 作为第二个论点。


4
2017-08-06 16:00



更改后,使用g ++ 4.4.4按预期编译和运行 initializer 至 initializer_list - Cubbi
@Cubbi:哦,是的。修复。 - Mike Seymour


表达式的类型 {1,2,3,4,5} 是 std::initializer_list<int>。它是一个具有成员函数的对象 size()begin()end(), 但不是 operator[] (每 18.9/1 C ++ 0x FCD)

如果你的函数使用std :: vector或任何其他标准容器,这将起作用,因为容器可以从initializer_lists构造(它们都提供了非显式的构造函数):

void someFunction(std::vector<int> araye)
{
         for (int i=0;i<5;i++)
                   std::cout << araye[i] <<' ';
         std::cout <<'\n';
}
int main()
{
        someFunction({1,2,3,4,5});
}

如果你想拥有一个带指针的函数,你需要以某种方式手动将initializer_list转换为你可以以这种方式访问​​的东西:

void someFunction(int* araye)
{
         for (int i=0;i<5;i++)
                   std::cout << araye[i] <<' ';
         std::cout <<'\n';
}
void someFunction(std::vector<int> v)
{
        someFunction(&v[0]);
}
int main()
{
        someFunction({1,2,3,4,5});
}

4
2017-08-06 14:53



如果你这样可能会更有效率 move 该 initializer_list。 - Jon Purdy
@Jon:你能扩展一下吗? - sbi
@sbi:没关系,请看@ David的回答。你可以写 someFunction(std::initializer_list<int> v) { someFunction(v.begin()); } 相反,这避免了复制 initializer_list 进入 vector。 - Jon Purdy
@Je Purdy:好点。我最初尝试过,但没有 const 它没有编译,我没有想到。 - Cubbi


维基百科 似乎建议你可以做到这一点,但只能通过声明函数来获取 std::initializer_list<int> 作为一个论点。


2
2017-08-06 14:30



是的,但这与单个指针不同。 - Pooria
@Pooria:根据实施情况,可能会也可能不会。一个实现是免费的 initializer_list<T> 但是,在符合标准的范围内,它基本上是令人高兴的。它可能只是静态数据区域中的一个数组,而且是 begin()方法可能只返回一个 const T*。 - Jon Purdy
@Jon:根据C ++ 0x草案标准, begin()  不 回来一个 const T*。 - Mike Seymour
@Mike:嗯,你去吧。请参阅@ Cubbi的回答评论。 - Jon Purdy