【问题标题】:C array vs pointer : array is considered as a variable, array+0 is considered as a pointer?C数组vs指针:数组被视为变量,array+0被视为指针?
【发布时间】:2012-07-30 11:54:04
【问题描述】:

我在 C++ 中创建了一个容器类,并且我有一个来自迭代器的构造函数,因此我可以编写 MyContainer<double> x(v.begin(), v.end()),其中 vstd::vector<double>。我希望能够对 c-array 做同样的事情,但是:

double array[3] =  {1., 2. , 3.};
MyContainer<double> x(array, array+3); // Doesn't work : no matching function for call to ‘MyContainer<double>::MyContainer(double [3], double*)’
MyContainer<double> x(array+0, array+3); // Work

问题的根源是什么,如何解决?

非常感谢。

【问题讨论】:

  • 愿意分享您的构造函数的签名吗?
  • 请显示所涉及的(模板?)构造函数的声明。
  • 猜猜这是MyContainer&lt;double&gt;::MyContainer(double*, double*)
  • 有趣的事实:+ array(一元加号运算符)也可以。

标签: c++ arrays pointers constructor


【解决方案1】:

不接受对迭代器的引用,按值获取。它试图传递对数组的引用;失败的表达式需要数组衰减到一个指针。

大概你有

template< typename Iter >
MyContainer( Iter const &first, Iter const &last );

但你需要

template< typename Iter >
MyContainer( Iter first, Iter last );

迭代器需要足够轻量级才能按值传递;所有标准模板都这样做。

数组不能用作迭代器,因为它不能递增。存储是固定的。当您在 arr + 0 之类的表达式中使用数组或将其按值传递给函数时,它会隐式转换为指向其第一个元素的指针。但是通过引用传递时不会发生这种转换。

【讨论】:

    【解决方案2】:

    array+0 的结果是一个指针,而array 本身不是一个指针,它是一个数组。您的构造函数没有采用数组和指针的重载,因此编译失败。

    处理从数组创建开始和结束迭代器问题的惯用方法是使用begin(...)end(...) 函数:

    MyContainer<double> x(std::begin(array), std::end(array));
    

    重载负责确定数组的末尾在哪里,从而使您无需将数组的长度添加到指针中。

    【讨论】:

    • 我曾经认为array&amp;array[0] 相同,因此是指向数组第一个字段的指针。我错了吗?
    • @AFriedrich 是的,你完全错了。尽管数组当然可以用作等于&amp;array[0] 的指针,并且在传递给函数时它们也可以decay 指向指针,但它们具有指针所缺乏的属性。它们的大小可以通过sizeof 获得,当它们作为structs 的成员包含时,它们会按值复制。实际上,将数组包装在 struct 中是您可以用来按值传递数组的技巧,而不是通过指针传递它。
    猜你喜欢
    • 2020-11-04
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多