如何将一个常量数组传递给一个不带variablesC / C ++的指针的函数?

如果我有一个看起来像这样的原型:

function(float,float,float,float) 

我可以传递这样的值:

 function(1,2,3,4); 

所以如果我的原型是这样的:

 function(float*); 

有什么办法可以实现这样的事情吗?

 function( {1,2,3,4} ); 

只是寻找一个懒惰的方式来做到这一点,而不创build一个临时variables,但我似乎无法指定语法。

你可以用C99(而不是 ANSI C(C90)或C ++的任何当前版本)来完成这个工作。 有关血淋淋的详细信息,请参阅C99标准的6.5.2.5节。 这是一个例子:

 // f is a static array of at least 4 floats void foo(float f[static 4]) { ... } int main(void) { foo((float[4]){1.0f, 2.0f, 3.0f, 4.0f}); // OK foo((float[5]){1.0f, 2.0f, 3.0f, 4.0f, 5.0f}); // also OK, fifth element is ignored foo((float[3]){1.0f, 2.0f, 3.0f}); // error, although the GCC doesn't complain return 0; } 

GCC也提供这个作为C90的扩展。 如果使用-std=gnu90 (缺省值),- -std=c99-std=gnu99编译,则会编译; 如果使用-std=c90编译,则不会。

这标记为C和C ++,所以你会得到完全不同的答案。

如果你期待四个参数,你可以这样做:

 void foo(float f[]) { float f0 = f[0]; float f1 = f[1]; float f2 = f[2]; float f3 = f[3]; } int main(void) { float f[] = {1, 2, 3, 4}; foo(f); } 

但这是不安全的,因为你可能会偶然这样做:

 void foo(float f[]) { float f0 = f[0]; float f1 = f[1]; float f2 = f[2]; float f3 = f[3]; } int main(void) { float f[] = {1, 2}; // uh-oh foo(f); } 

通常最好将它们作为单独的参数。 既然你不应该使用原始数组,你可以这样做:

 #include <cassert> #include <vector> void foo(std::vector<float> f) { assert(f.size() == 4); float f0 = f[0]; float f1 = f[1]; float f2 = f[2]; float f3 = f[3]; } int main(void) { float f[] = {1, 2, 3, 4}; foo(std::vector<float>(f, f + 4)); // be explicit about size // assert says you cannot do this: foo(std::vector<float>(f, f + 2)); } 

一个改进,但没有太多的一个。 你可以使用boost::array ,而不是一个错误的大小不匹配,他们被初始化为0:

 #include <boost/array.hpp> void foo(boost::array<float, 4> f) { float f0 = f[0]; float f1 = f[1]; float f2 = f[2]; float f3 = f[3]; } int main(void) { boost::array<float, 4> f = {1, 2, 3, 4}; foo(f); boost::array<float, 4> f2 = {1, 2}; // same as = {1, 2, 0, 0} foo(f2); } 

这将全部在C ++ 0x中被修复,当初始化列表构造函数被添加时:

 #include <cassert> #include <vector> void foo(std::vector<float> f) { assert(f.size() == 4); float f0 = f[0]; float f1 = f[1]; float f2 = f[2]; float f3 = f[3]; } int main(void) { foo({1, 2, 3, 4}); // yay, construct vector from this // assert says you cannot do this: foo({1, 2}); } 

也可能是boost::array

 #include <boost/array.hpp> void foo(boost::array<float, 4> f) { float f0 = f[0]; float f1 = f[1]; float f2 = f[2]; float f3 = f[3]; } int main(void) { foo({1, 2, 3, 4}); foo({1, 2}); // same as = {1, 2, 0, 0} ..? I'm not sure, // I don't know if they will do the check, if possible. } 

你可以创build一个复合文字:

 function ((float[2]){2.0, 4.0}); 

虽然,我不知道为什么你想要经历麻烦。 ISO不允许这样做。

一般来说,在所有情况下都应避免使用这样的快捷方式,以提高可读性。 懒惰不是一个好习惯(当然,个人意见)

坏消息是没有这个语法。 好消息是,随着C ++标准的下一个正式版本(未来一两年),这将会发生变化。 新的语法看起来和你描述的一模一样。

你可以在技术上参考数组,但你仍然不能创build我认为的匿名初始化列表。

 void func(int (&bla)[4]) { int count = sizeof(bla)/sizeof(bla[0]); // count == 4 } int bla[] = {1, 2, 3, 4}; func(bla); int bla1[] = {1, 2}; func(bla1); // <-- fails 

对于C ++方式,请看boost :: assign 。 相当整洁的方式填写STL容器。

不,你不能这样做。 我没有这里的标准,所以我不能给出一个确切的参考,但最接近你要求的是string常量,即

 function(char *); function("mystring"); 

被编译器视为

 char * some_pointer = "mystring"; function(char *); function(some_pointer); 

其他types的variables无法以这种方式处理。

可悲的是,它只适用于字符数组:

 void func2(char arg[]) { } int main() { func2("hello"); return 0; } 

你可以编写一个构build器类来允许大致相同的语法

 // roughly template <typename C> class Builder { public: template <typename T> Builder(const T & _data) { C.push_back(_data); } template <typename T> Builder& operator()(const T & _data) { C.push_back(_data); return *this; } operator const C & () const { return data; } private: C data; }; 

这样,你可以使用类作为

foo(const std :: vector&v);

foo(Builder <std :: vector>(1)(2)(3)(4));

为了增加乐趣,可以使用模板使其长度可变。

 template<std::size_t N> int chars(const char(&r)[N]){ std::cout << N << ": " << r << std::endl; return 0; } template<std::size_t N> int floats(const float(&r)[N]){ std::cout << N << ":"; for(size_t i = 0; i < N; i++) std::cout << " " << r[i]; std::cout << std::endl; return 0; } int main(int argc, char ** argv) { chars("test"); floats({1.0f, 2.0f, 3.0f, 4.0f}); return 0; }