Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C++; 我正在重构一些使用SLoeBER(AutoNo插件for Eclipse)的AVR项目的C++代码。该项目有许多存储在EEPROM中的“设置”变量,有上限和下限,需要字符串标签等。这些设置是不同的整数类型(uint8_t,int32_t,等等),我想要一个包装器,可以包含这些类型中的任何一种,并从基类继承一些方法。我还希望能够形成一个包含所有设置变量的数组,这样我就可以遍历它们_C++_Wrapper_Stdint - Fatal编程技术网

在C++; 我正在重构一些使用SLoeBER(AutoNo插件for Eclipse)的AVR项目的C++代码。该项目有许多存储在EEPROM中的“设置”变量,有上限和下限,需要字符串标签等。这些设置是不同的整数类型(uint8_t,int32_t,等等),我想要一个包装器,可以包含这些类型中的任何一种,并从基类继承一些方法。我还希望能够形成一个包含所有设置变量的数组,这样我就可以遍历它们

在C++; 我正在重构一些使用SLoeBER(AutoNo插件for Eclipse)的AVR项目的C++代码。该项目有许多存储在EEPROM中的“设置”变量,有上限和下限,需要字符串标签等。这些设置是不同的整数类型(uint8_t,int32_t,等等),我想要一个包装器,可以包含这些类型中的任何一种,并从基类继承一些方法。我还希望能够形成一个包含所有设置变量的数组,这样我就可以遍历它们,c++,wrapper,stdint,C++,Wrapper,Stdint,要演示的简单实现如下所示: // Base class storing a uint8_t by default class Base { public: typedef uint8_t numType; numType value = 0; }; // Child class changing 'numType' to a uint16_t class Child: public Base { public: typedef uint16_t numType; };

要演示的简单实现如下所示:

// Base class storing a uint8_t by default
class Base {
  public:
  typedef uint8_t numType;
  numType value = 0;  
};

// Child class changing 'numType' to a uint16_t
class Child: public Base {
  public:
  typedef uint16_t numType;
};
然后运行以下命令:

Base baseObj;
baseObj.value = 123;

Child childObj;
childObj.value = 12345;
我的意图是
childObj.value
将是
uint16\u t
,而
baseObj.value
将保持
uint8\u t


但是
childObj.value
的计算结果为
57
,因此它仍然被视为
uint8\t
。关于实现这类事情的方法有什么想法吗?

除非子类有其他独特的行为,否则您只需要将
基作为模板:

模板
结构基
{
使用numType=T;
numType值=0;
};
然后,可以为所需的不同整数类型创建此类型的类型别名:

using Uint8 = Base<uint8_t>;
using Uint16 = Base<uint16_t>;
使用Uint8=Base;
使用Uint16=基准;

您需要的是一种类型擦除。您可以直接使用
std::any
(如果您只存储了一个值,这将是有意义的),也可以构建自己的:

class Setting {
 public:
  Setting(std::string description) : _description(description) {}
  virtual ~Setting() = 0;

  std::string getDescription();

  template<typename T>
  T getValue();

 private:
  std::string _description;
};

template <typename T>
class SettingTyped : public Setting {
 public:
  SettingTyped(T value, std::string description)
      : Setting(description), _value(value) {}

  T getValue() { return _value; }

 private:
  T _value;
};

Setting::~Setting() = default;

template<typename T>
T Setting::getValue()
{
    auto* typedSetting = dynamic_cast<SettingTyped<T>*>(this);
    if (!typedSetting)
        throw std::runtime_error("Accessing with wrong type!");
    return typedSetting->getValue();
}

template<typename T>
auto makeSetting(T value, std::string description)
{
    return std::make_unique<SettingTyped<T>>(value, description);
}

bool foo() {
  std::vector<std::unique_ptr<Setting>> settings;
  settings.push_back(makeSetting<int>(3, "a setting"));

  return (settings[0]->getValue<int>() == 3);
}
类设置{
公众:
设置(std::string description):\u description(description){}
虚拟~设置()=0;
std::string getDescription();
模板
T getValue();
私人:
std::字符串_描述;
};
模板
类设置类型:公共设置{
公众:
SettingTyped(T值,标准::字符串描述)
:设置(说明),_值(值){
T getValue(){return_value;}
私人:
T_值;
};
设置::~Setting()=默认值;
模板
T设置::getValue()
{
auto*typedSetting=动态转换(此);
如果(!typedSetting)
抛出std::runtime_错误(“使用错误类型访问”);
返回typedSetting->getValue();
}
模板
自动生成设置(T值,标准::字符串描述)
{
返回标准::使_唯一(值、描述);
}
布尔福(){
std::向量设置;
设置。向后推(makeSetting(3,“a设置”);
返回(设置[0]->getValue()==3);
}

您可以使用它来了解如何区分“原型设置”(默认值、边界)和“当前设置值”(实际存储值)。例如,您仍然可以决定边界是否应在设置类型中进行编码(并为每种设置创建单独的类型),或者边界是否(可能)为每个实例的不同常量。从你的问题来看,这方面的要求并不明确


尤其不清楚的是,在遍历每个设置时,您希望如何知道它们的正确类型。这里假设您不知何故知道(例如,基于描述?)

如果您想要形成一个基数组(使用不同的包装类型),则无法对基进行模板化,这就是问题所指定的。
class Setting {
 public:
  Setting(std::string description) : _description(description) {}
  virtual ~Setting() = 0;

  std::string getDescription();

  template<typename T>
  T getValue();

 private:
  std::string _description;
};

template <typename T>
class SettingTyped : public Setting {
 public:
  SettingTyped(T value, std::string description)
      : Setting(description), _value(value) {}

  T getValue() { return _value; }

 private:
  T _value;
};

Setting::~Setting() = default;

template<typename T>
T Setting::getValue()
{
    auto* typedSetting = dynamic_cast<SettingTyped<T>*>(this);
    if (!typedSetting)
        throw std::runtime_error("Accessing with wrong type!");
    return typedSetting->getValue();
}

template<typename T>
auto makeSetting(T value, std::string description)
{
    return std::make_unique<SettingTyped<T>>(value, description);
}

bool foo() {
  std::vector<std::unique_ptr<Setting>> settings;
  settings.push_back(makeSetting<int>(3, "a setting"));

  return (settings[0]->getValue<int>() == 3);
}