c++ 传递一个C-数组到一个函数中,该函数需要一个C-数组,而不需要定义一个变量

cyvaqqii  于 2023-05-02  发布在  其他
关注(0)|答案(5)|浏览(188)

对于C,e,存在许多类似的问题。例如this one,但我正在寻找C++中最简单和最可读的方法来将C数组传递到函数中,而无需首先为其定义变量。
给定void f(double const* a),这些是不可能的(但the first one is in C99):

f((double []){1,2}); // works in C
f({1,2}); // would be great but doesn't work in any language with C-arrays

当然首先定义一个变量总是可能的,但这不是我要找的:

double a[] = { 1.2, 3.4 };
f(a);

但是,可以将东西 Package 到结构体f中。即喜欢

struct A { double a[2]; };
f(A{2.3,4.5}.a);

而且这种类型可以重用,所以这已经是一个小胜利了
Live Demo
但还是觉得很笨拙
有没有更简单、更易读的方法?在当前的标准之一或即将到来的标准中?

编辑:对不起,我之前没有提到;我无法更改目标API。需要指向双精度型的指针。

vulvrdjw

vulvrdjw1#

这个函数很棒:

template<typename T, std::size_t N>
constexpr T* temporary_array(T(&& arr)[N]) noexcept { return arr; }

然后,您可以简单地调用f(temporary_array<double>({1,2}));(或f(temporary_array({1., 2.})))。
在C20中,你可以写f(std::type_identity_t<double(&&)[]>{1,2})f(std::type_identity_t<double[]>{1, 2})也应该在任何C版本中工作,但GCC有一个长期存在的错误,不允许编译。
寻找标准库解决方案,您的struct A可以替换为std::array<double, 2>。写出size参数很烦人,但可以用CTAD代替:

f(std::array{ 1., 2. }.data());
f(std::array<double, 2>{1, 2}.data());
// (These will call move constructors)
f(std::to_array<double>({1, 2}).data());
f(std::to_array({1., 2.}).data());
xj3cbfub

xj3cbfub2#

vector代替double*怎么样?然后你可以在调用站点构建一个in-place,如下所示:

#include<vector>

double f(std::vector<double> const& v)
{
  return v[0];
}

int main()
{
  f({1,2,3});
}
xkrw2x1b

xkrw2x1b3#

如果你能用c++20编译,那么最明显的答案是使用std::span,以获得最大的灵活性。
Demo:

#include <array>
#include <span>
#include <vector>

void f(std::span<const double> a);

int main()
{
    f({{1.0, 2.0, 3.3}});

    double ca[] = { 1.2, 3.4 };
    f(ca);

    std::vector<double> v = { 1.2, 3.4 };
    f(v);

    std::array a = { 1.2, 3.4 };
    f(a);
}
68bkxrlz

68bkxrlz4#

如果要避免动态分配,请使用std::initializer_list

template <typename T>
void f(const std::initializer_list<T>& v)
{
    for (const auto& e : v)
        std::cout << e << " ";
    std::cout << "\n";
}

int main()
{
    f({1,2,3});
    f({4.0,5.1,6.2});
}

产出
Live example

bxfogqkk

bxfogqkk5#

你的函数签名是错误的。它可以被修复和改进。参见:https://godbolt.org/z/WoME5xazr

#include <iostream>

void foo(double (&arr)[])
{
    std::cout<<arr[0]<<std::endl;
}
template<size_t N>
void BetterFoo(double (&arr)[N])
{
    for (size_t i = 0;i<N;++i)
    {
        std::cout<<arr[i]<<std::endl;
    }
}

int main()
{
    double a[] = { 1.2, 3.4 };
    foo(a);
    std::cout<<"better foo"<<std::endl;
    BetterFoo(a);
    return 0;
};

希望能帮上忙

相关问题