C++1z(?)运行时大小的数组作为返回值

C++1z(?) runtime sized array as a return value

本文关键字:数组 返回值 运行时 C++1z      更新时间:2023-10-16

我们可以不做这样的事情吗?

auto f(int n, char *arr[]) -> decltype(char *[n]) /* doesn't work */ {
    char *tmp[n]; // RSA, the size depends on argc
    for (int i = 0; i < n; ++i) tmp[i] = arr[i];
    return tmp;
}
int main(int argc, char *argv[]) {
    auto arr = f(argc, argv);
    for (auto e : arr)
        cout << e << endl;
}

我喜欢值语义(只要我的编译器能够进行正确的内联),尤其是当我将一个大函数重构为一组较小的实用程序时。

编辑:哎呀,它没有变成C++14…(标题从"C++14"改为"C++1z(?)"。)"阵列扩展TS"怎么样?它支持这样的东西吗?

执行您想要执行的操作的规范C++方法是使用std::vector(如果在编译时元素数量已知,则使用std::array)。C++不使用VLA,正如M.M的回答中所指出的那样。

如果所涉及的字符指针不会悬空(例如,在argv的情况下),您可以这样做:

std::vector<char*> f(int n, char** arr)
{
    std::vector<char*> tmp;
    tmp.reserve(n);
    for (int i = 0; i < n; ++i)
        tmp.push_back(arr[i]);
    return tmp;
}

如果指针将挂起,最好创建std::string对象:

std::vector<std::string> f(int n, char** arr)
{
    std::vector<std::string> tmp;
    tmp.reserve(n);
    for (int i = 0; i < n; ++i)
        tmp.emplace_back(arr[i]);
    return tmp;
}

emplace_back是C++11中的新成员。在较旧的C++版本中,您可以只使用push_back。)

VLA在任何版本的ISO C++中都是不允许的。

一些编译器提供VLA作为扩展。您需要查阅编译器的文档,以了解有关扩展性质的详细信息。

在我看来,返回VLA不太可能被任何扩展所允许(或者如果VLA进入,则被C++17所允许),因为返回数组(即使是非VLA)也没有意义。

没有指定按值返回数组的语法;在return tmp;行中tmp衰减为指针。数组没有值语义。