【问题标题】:Extended initializer lists and arrays扩展初始化列表和数组
【发布时间】:2012-11-13 08:45:10
【问题描述】:

我有简单的功能,例如:

void fun(vector<int> vec)
{
//...
}

void fun(int* smth)
{
//...
}

当我写在我的程序中时没有。

fun({2,3});

向量参数让我觉得很有趣,我知道它在新的 C++ 扩展初始化列表中,但我想使用新的 C++ 并告诉编译器这只是一个 int 数组,我该怎么做?

编辑:

最好在 1 行中完成 :)

【问题讨论】:

  • 幸运的是,C++ 中不能有临时数组。
  • @kerrek 不正确。我惹恼了马德里的委员会,直到他们接受了 C++11。
  • It would be nice to do it in 1 line :) 为什么?
  • @JohannesSchaub-litb:我从来不知道——那是标准的哪一部分?
  • @KerrekSB 没有特别的部分。它只是不被允许。我发邮件说有几个段落没有禁止临时数组的某些用途,而其他段落部分相互矛盾。并决定摆脱所有禁止或妨碍临时数组的规则。

标签: c++ arrays c++11 initializer-list


【解决方案1】:

您不能用数组初始化指针,因为指针不是数组(尽管在某些情况下会出现这种情况,但事实并非如此)。

您必须将指针传递给预先存在的数组。或者,使用vector 重载——当然,你还是更喜欢这个?!如果这两个函数做不同的事情,那么为什么它们会互相重载(即为什么重要)?

【讨论】:

  • 将指针传递给预先存在的数组会用数组初始化指针,不是吗?
  • @JohannesSchaub-litb:不。在用这个指针初始化参数的指针之前,它将用数组第一个元素的地址填充指针。除了实际数组本身之外,任何阶段都不会使用数组初始化任何内容。
  • @JohannesSchaub-litb:没问题。
【解决方案2】:

制作别名模板

template<typename T>
using identity = T;

所以你可以写

fun(identity<int[]>{1,2});

但这不是好的编程,因为在你的函数中你无法知道指向的数组的大小。如果该函数应该与元素列表一起使用,则应将其显式传递给该函数。如果您想处理数组,请考虑使用 llvm::ArrayRef&lt;T&gt; 之类的东西或创建自己的

struct array_ref {
public:
  template<int N>
  array_ref(const identity<int[N]> &n)
    :begin_(n), end_(n + N)
  { }

  array_ref(const std::vector<int>& n)
    :begin_(n.data()), end_(n.data() + n.size())
  { }

public:
  int const *begin() const { return begin_; }
  int const *end() const { return end_; }
  int size() const { return end_ - begin_; }

private:
  int const *begin_;
  int const *end_;
};

void fun(array_ref array) {
  ...
}

int main() {
  fun(array_ref(identity<int[]>{1,2}));
}

【讨论】:

  • 但这不应该是必要的。向量重载应该做同样的事情,所以 OP 应该对使用它感到满意!
  • @light no 向量重载将分配动态内存。在某些环境中这是不行的。
  • 您认为在这种情况下,这是一个认真考虑的可能性有多大?
  • @LightnessRacesinOrbiti 我不知道。
  • array_refbasic_string_refproposed for standardization,所以希望我们能在 C++14 中看到它们。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
  • 2023-03-13
相关资源
最近更新 更多