C++ 如何在不使用变量C/C+的情况下将常量数组文本传递给接受指针的函数+;?

C++ 如何在不使用变量C/C+的情况下将常量数组文本传递给接受指针的函数+;?,c++,c,function,C++,C,Function,如果我有一个这样的原型: function(float,float,float,float) function(1,2,3,4); 我可以这样传递值: function(float,float,float,float) function(1,2,3,4); 如果我的原型是这样的: function(float*); 我有没有办法做到这一点 function( {1,2,3,4} ); 我只是在寻找一种不创建临时变量的惰性方法,但我似乎无法确定语法。坏消息是没有语法。好消息是,这将随着

如果我有一个这样的原型:

function(float,float,float,float)
function(1,2,3,4);
我可以这样传递值:

function(float,float,float,float)
function(1,2,3,4);
如果我的原型是这样的:

function(float*);
我有没有办法做到这一点

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

我只是在寻找一种不创建临时变量的惰性方法,但我似乎无法确定语法。

坏消息是没有语法。好消息是,这将随着下一个官方版本的C++标准(在未来一两年内)而改变。新语法将与您描述的完全相同。

不,您不能这样做。我这里没有可用的标准,所以我无法给出准确的参考,但最接近您要求的是字符串常量,即

function(char *);
function("mystring");
被编译器视为

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

其他类型的变量无法以这种方式处理。

您可以创建一个复合文字:

function ((float[2]){2.0, 4.0});
虽然,我不知道你为什么要经历这些麻烦。这是ISO不允许的


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

不幸的是,它只适用于角色数组:

void func2(char arg[]) {
}

int main()
{   
    func2("hello");
    return 0;
}

<>这是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);
}
#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));
}
但这是相当不安全的,因为你可能会意外地这样做:

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);
}
通常最好将它们作为单独的参数。由于您无论如何都不应该使用原始数组,因此可以执行以下操作:

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);
}
#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));
}
在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});
}
您可以在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
编译,则不会编译。

您可以编写一个生成器类,该类允许使用大致相同的语法

// 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;

};
//大概
模板
类生成器{
公众:
模板
生成器(const T&_data){C.push_back(_data);}
模板
生成器和运算符()(常量和_数据){
C.推回(数据);
归还*这个;
}
运算符常量C&()常量{返回数据;}
私人:
C数据;
};
这样,您就可以将该类用作

foo(const std::vector&v)


foo(Builder(1)(2)(3)(4))

从技术上讲,您可以引用数组,但我认为您仍然无法创建匿名初始值设定项列表

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
void func(int&bla)[4])
{
int count=sizeof(bla)/sizeof(bla[0]);
//计数==4
}
int bla[]={1,2,3,4};
func(bla);
int bla1[]={1,2};

func(bla1);// 为了增加乐趣,您可以使用模板使其长度可变

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;
}
模板
int字符(常量字符(&r)[N]){

std::我是否同意可读性,在实践中,这个特定的函数将被传递一个内存地址,并且会很高兴。但是,在测试期间,我通常只想插入一些随机值。您的代码片段实现了这个技巧,无论是好是坏:)谢谢!C99是“ISO”允许标准中的复合文字。它不在C90上可用,也不可移植到C++。呵呵,明年或两年:很好地知道这将是在C++ 0x中。我怀疑两年了。Visual Studio的beta 10已经内置了一些C++ 0x特性,并且G+ 4.4已经有初始化列表()。。它被推迟到2010年,可能是第一季度。谢谢你的建议。我想我希望一个又快又脏的问题能得到快速又脏的答案,但你的回答探索了一些我没有想到的替代样式。非常感谢!显然你也可以用
-std=gnu89
编译(但不是
-std=c89
),因为它是
-std=gnu90
(和
-std=c90
)的同义词(我相信你知道这个Adam,如果其他人不知道的话,这对他们来说更重要:P)。这不是一个好的解决方案,因为你不会知道传递的参数的长度。