【问题标题】:can we pass arrays as arguments to functions by this syntax, under upcoming c++0x standards?在即将到来的 c++0x 标准下,我们可以通过这种语法将数组作为参数传递给函数吗?
【发布时间】:2010-08-06 14:26:44
【问题描述】:

假设我们有以下函数:

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 中拉出一个指针并将其传递给预期的函数,但在我看来,这种方法就像一个黑客能够将该表达式用作参数的预期函数,也就是说,当我的预期函数参数是单个指针时,我认为我根本不应该将该表达式用作参数,或者可能有另一种使用方法那个表情? .

【问题讨论】:

  • 那太好了,像对待char 数组一样对待int 数组已经永远......

标签: c++ arrays function syntax c++11


【解决方案1】:

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

如果您的函数采用 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});
}

【讨论】:

  • 如果你moveinitializer_list会更高效。
  • @Jon:你能扩展一下吗?
  • @sbi:没关系,请参阅@David 答案中的 cmets。你可以只写someFunction(std::initializer_list&lt;int&gt; v) { someFunction(v.begin()); },这样可以避免将initializer_list复制到vector中。
  • @Jon Purdy:好点子。我最初尝试过,但没有const,它没有编译,我没有考虑。
【解决方案2】:

如果您的函数采用const int*,而不是int*,那么您只需要一个小的蹦床函数将指针从大括号初始化程序生成的std::initializer_list&lt;int&gt; 中拉出。像这样的东西(可能;我没有 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() 作为第二个参数传递。

【讨论】:

  • 在将 initializer 更改为 initializer_list 后,使用 g++ 4.4.4 编译并按预期运行
【解决方案3】:

Wikipedia 似乎暗示您可以这样做,但只能通过声明函数将std::initializer_list&lt;int&gt; 作为参数。

【讨论】:

  • @Pooria:取决于实现,它可能是也可能不是。在符合标准的范围内,实现基本上可以随意处理initializer_list&lt;T&gt;。它可能只是静态数据区中的一个数组,begin() 方法可能只返回一个const T*
  • @Jon:根据 C++0x 草案标准,begin()确实只返回一个const T*
  • @Mike:好吧,你去吧。请参阅@Cubbi 答案的评论。
猜你喜欢
  • 1970-01-01
  • 2023-02-09
  • 2011-03-16
  • 2011-02-20
  • 1970-01-01
  • 2011-03-16
  • 2015-10-26
  • 1970-01-01
  • 2021-09-14
相关资源
最近更新 更多