有没有办法在C++中传递匿名数组作为参数?

Jer*_*ner 27 c++ arrays arguments

我希望能够在C++中将数组声明为函数参数,如下面的示例代码所示(不编译).有没有办法做到这一点(除了预先单独声明数组)?

#include <stdio.h>

static void PrintArray(int arrayLen, const int * array)
{
   for (int i=0; i<arrayLen; i++) printf("%i -> %i\n", i, array[i]);
}

int main(int, char **)
{
   PrintArray(5, {5,6,7,8,9} );  // doesn't compile
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

rlb*_*ond 30

如果您使用较旧的C++变体(前C++ 0x),则不允许这样做.您引用的"匿名数组"实际上是初始化列表.既然C++ 11已经用完了,可以使用内置initializer_list类型完成.理论上extern C,如果你的编译器将它们解析为C99或更高版本,也可以使用它作为C风格的初始化列表.

例如:

int main()
{
    const int* p;
    p = (const int[]){1, 2, 3};
}
Run Code Online (Sandbox Code Playgroud)

  • 只要你对文字进行类型转换,GCC实际上是可以的:p =(int []){1,2,3}; 按照亚当在下面的回答方式. (9认同)
  • 这是真的,但只是为其他读者重申,它不是可移植的c ++. (6认同)

Ada*_*eld 30

在C++ 11和extern "C"C99 中使用类型转换是允许的:

void PrintArray(size_t len, const int *array)
{
    for(size_t i = 0; i < len; i++)
        printf("%d\n", array[i]);
}

int main(int argc, char **argv)
{
    PrintArray(5, (const int[]){1, 2, 3, 4, 5});
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


nit*_*ria 19

编译,但我不推荐它.

#include <stdio.h>

struct arr
{
   int array[5];
};

static void PrintArray(int arrayLen, arr array)
{
   for (int i=0; i<arrayLen; i++) printf("%i -> %i\n", i, array.array[i]);
}

int main(int, char **)
{
   PrintArray(5, (arr){5,6,7,8,9});
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 这很聪明 - 因为额外的hackiness你可以把它与结构的最后一个元素结合起来,arr :: array不必有一个显式的维度(这将允许它与任何大小的数组一起使用),以及也许让arr成为一个模板,这将允许它与任何类型一起使用. (3认同)

ova*_*nes 8

免责声明:对于这个答案,我得到了一些downvotes,但它起源于2009年,C++ 11即将被定义.对于现代C++,请在下面滚动.

好吧,尝试使用boost ...

这是使用boost :: assign库的解决方案和更多C++编程;)

#include <boost/assign/list_of.hpp>

#include <iostream>
#include <algorithm>


namespace
{
  template<class CollectionT>
  void print(CollectionT const& coll)
  {
    std::ostream_iterator<int> out(std::cout, ", ");
    std::copy(coll.begin(), coll.end(), out);
  }
}



int main()
{
  using namespace boost::assign;

  print( list_of(1)(2)(3)(4)(5) );

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

C++ 11及更高版本,具有特定功能的说明

符合clang: clang++ -std=c++14 -I /usr/local/include/ main.cpp

#include <boost/assign/list_of.hpp>

#include <iostream>
#include <iterator>
#include <algorithm>
#include <initializer_list>


template<typename CollectionT, typename OStream>
auto // <- auto result type deduction from C++ 14
  make_output_iterator(CollectionT const& coll, OStream& out)
{
  return std::ostream_iterator<typename CollectionT::value_type>(out, ", ");
}

// here template specialization is used, to demonstrate initializer lists from C++ 11
template<typename T>
void print(std::initializer_list<T> items)
//         ^----------------------^ passed by value due to move semantics
{
  using namespace std;
  cout << "printing an initializer list: ";
  copy(items.begin(), items.end(), make_output_iterator(items, cout));
  cout << endl;
}


template<typename CollectionT>
void print(CollectionT const& items)
{
  using namespace std;
  cout << "printing another collection type: ";
  copy(items.begin(), items.end(), make_output_iterator(items, cout));
  cout << endl;
}


int main()
{
  print({0,1,2,3,4,5,6,7,9});

  using namespace boost::assign;
  print( list_of(0)(1)(2)(3)(4)(5)(6)(7)(8)(9) );
}
Run Code Online (Sandbox Code Playgroud)


Joe*_*e D 5

使用 C++0x,您可以使用std::initializer_list(和 foreach 循环)

#include <iostream>
#include <initializer_list>

void print (const std::initializer_list<int>& array)
{
    for (auto x : array) // C++0x foreach loop
        std::cout << x << std::endl;
}

int main (int argc, char ** argv)
{
    print ({ 1, 2, 3, 4, 5 });
}
Run Code Online (Sandbox Code Playgroud)


Rus*_*lan 5

从 C++11 开始,您可以使用std::begin(std::initializer_list const&)来获取指针。例子:

#include <iostream>
void func(int len, const int* x)
{
    for(int i=0;i<len;++i)
        std::cout << x[i] << "\n";
}
int main()
{
    func(5, std::begin({1,3,6,823,-35}));
}
Run Code Online (Sandbox Code Playgroud)

与接受的答案不同,这确实是与标准兼容的代码。