【问题标题】:C++ inline array member uniform initializationC++ 内联数组成员统一初始化
【发布时间】:2019-12-07 09:39:42
【问题描述】:

假设您有一个具有数组成员的类:

class A
{
private:
    uint8_t length;
    uint8_t arr[10];
public:
    A(uint8_t length, const uint8_t array[]): length(length)
    {
        memcpy(arr, array, length);
    }
};

然后你有一个全局常量对象,你想像这样使用统一初始化:

const A A_CONST{1,{23}};

在这种情况下,编译器会报错:“invalid conversion from 'int' to 'const uint8_t*”

但这有效:

const uint8_t arr[]={23};
const A A_CONST{1,arr};

但是你也有一个不必要的全局常量“arr”。我不明白为什么编译器不能通过查看构造函数将 {23} 转换为 const uint8_t* 。为什么会这样?有解决方法吗?

【问题讨论】:

  • 如果它适合您的用例,您可以删除构造函数,然后使用聚合初始化(您的初始化语句将起作用)
  • {23} 不是一个有效的指针初始化器(也不应该是)
  • 但是,可以像第二个例子那样初始化数组“arr”吗?
  • 你的最后一个例子是正确的,是的
  • 我想我希望对此有更多的了解。对我来说,这些初始化看起来完全一样。我只是不明白为什么第一次初始化失败而第二次初始化失败。在第二个中,您只有一个额外的中间人变量“arr”。我想编译器看到构造函数的时候应该明白第二个统一初始化参数{23}是一个常量数组。

标签: c++


【解决方案1】:

你定义的构造函数,相当于

A(uint8_t length, const uint8_t *array)

这就是编译器试图告诉的内容。

要像您的示例那样进行初始化,您必须使用其他类型或std::initializer_list,例如

#include <algorithm>
#include <initializer_list>

A(const std::initializer_list<uint8_t> array)
    : length(array.size())
{
    std::copy(array.begin(), array.end(), arr);
}

除此之外,不要使用普通数组或(长度,指针)参数。最好使用像 std::arraystd::vector 这样的现代类型,这样更不容易出错,而且您可以免费获得这种初始化。

【讨论】:

  • 我会使用 std::vector,但这是一个嵌入式系统,我正在尝试最小化代码占用空间。但这不是问题。
【解决方案2】:

如果你真的需要使用数组(而不是std::vector),你可以使用这个例子:

#include <cstring>
#include <cstdint>
#include <iostream>
#include <initializer_list>

class A
{
private:
  static const uint8_t MAX_LENGTH = 10;
  uint8_t length;
  uint8_t arr[MAX_LENGTH];
public:
  A(uint8_t _length, const uint8_t array[]): length(_length)
  {
    if (length > MAX_LENGTH) { // to prevent copying out of memory
      length = MAX_LENGTH;
    }
    std::memcpy(arr, array, length);
  }
  A(std::initializer_list<uint8_t> l): length(l.size())
  {
    if (length > MAX_LENGTH) { // to prevent copying out of memory
      length = MAX_LENGTH;
    }
    std::initializer_list<uint8_t>::iterator it = l.begin();
    for (uint32_t i = 0; (i < length) || (it == l.end()); ++i, ++it) {
      arr[i] = *it;
    }
  }
  uint8_t printAllForExample() const {
    for (uint32_t i = 0; i < length; ++i) {
      std::cout << (int)arr[i] << "  ";
    }
    std::cout << std::endl;
  }
  uint8_t getLengthForExample() const {
     return length;
  }
};

int main() {
  std::cout << "A_CONST_1:" << std::endl;
  const A A_CONST_1{23};
  A_CONST_1.printAllForExample();

  std::cout << "A_CONST_2:" << std::endl;
  const A A_CONST_2{};
  std::cout << (int)A_CONST_2.getLengthForExample() << std::endl;
  A_CONST_2.printAllForExample();

  std::cout << "A_CONST_3:" << std::endl;
  const A A_CONST_3{0,1,2,3,4,5,6,7,8,9};
  std::cout << (int)A_CONST_3.getLengthForExample() << std::endl;
  A_CONST_3.printAllForExample();

  std::cout << "A_CONST_4:" << std::endl;
  const A A_CONST_4{0,1,2,3,4,5,6,7,8,9,10,11,12};
  std::cout << (int)A_CONST_4.getLengthForExample() << std::endl;
  A_CONST_4.printAllForExample();

  uint8_t data[] = {30,40,50};
  std::cout << "A_CONST_5:" << std::endl;
  const A A_CONST_5(3, data);
  std::cout << (int)A_CONST_5.getLengthForExample() << std::endl;
  A_CONST_5.printAllForExample();
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-02
    • 2011-06-02
    • 1970-01-01
    • 2011-08-04
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多