使用各种数据类型的成员创建对象的简便方法

ere*_*ipS 3 c++ constructor initialization object c++11

在C ++中,我经常需要使用一个非常简单的原始对象,该对象仅包含各种数据类型,以便可以在函数之间轻松传递它。在Python中,我通过使用字典来实现这一点。例如:

easy = {"keyframe_range":[], "value":0.25, "interpolation":"bezier"}
Run Code Online (Sandbox Code Playgroud)

但是,在C ++中,如果我想创建类似的东西,则需要:

struct obj
{
  vector<int> keyframe_range;
  float value;
  string interpolation;

  obj(vector<int> vv, float ff, string ss) : keyframe_range(vv), value(ff), interpolation(ss) {}

};

obj easy(vector<int>(), 0.25, "bezier");
Run Code Online (Sandbox Code Playgroud)

当我需要一时兴起地创建知道对象的对象时,为我需要的每个对象手动编写一个参数化的构造函数是非常低效率的,而且浪费大量时间。在Python中,我基本上可以使用字典来避免这种情况;但是,C ++中的unordered_maps必须映射到相同的数据类型,因此它们并不是我真正想要的。

本质上,我只是想要一种简单的方法来创建一个简单的对象,该对象充当各种数据类型的项目的集合,仅此而已。可以在C ++ 11中完成吗?

for*_*818 9

为我需要的每个对象手动编写一个参数化的构造函数是非常低效率的,并且浪费大量时间。

我完全同意。但是,这没有问题,因为您实际上不需要为每个简单的结构编写构造函数:

#include <vector>
#include <string>
#include <iostream>

struct obj
{
    std::vector<int> keyframe_range;
    float value;
    std::string interpolation;
};

int main() {
    obj easy{ {}, 0.25, "bezier"};
    std::cout << easy.value << " " << easy.interpolation;        
}
Run Code Online (Sandbox Code Playgroud)

这称为聚合初始化,可以在类具有

  • 没有私有或受保护的直接(自C ++ 17起)非静态数据成员

  • 没有用户声明的构造函数(直到C ++ 11)

  • 没有用户提供的构造函数(明确允许使用默认或删除的构造函数)(自C ++ 11起)(直到C ++ 17)

  • 没有用户提供的,继承的或显式的构造函数(允许使用显式默认或删除的构造函数)(自C ++ 17起)(直到C ++ 20)

  • 没有用户声明或继承的构造函数[...]

还有其他一些限制,通常都适用于这样的简单结构(它们称为集合)。

本质上,我只是想要一种简单的方法来创建一个简单的对象,该对象充当各种数据类型的项目的集合,仅此而已。可以在C ++ 11中完成吗?

另外,您应该看一下std::tuple,尽管编写自己的类的好处是为成员赋予了有意义的名称,并且您可以区分类型std::tuple完全相同的类型。

另一方面,的优点std::tuple是它附带了operator<已经定义的几个运算符(例如)。因此,根据您的用例,您可以选择其中一个。

  • C ++ 20之前的版本的缺点是,您仍然必须实现比较运算符。一旦我们获得了“ auto operator(type const&)&lt;=&gt; = default;”,它将非常好。 (4认同)

Nat*_*ica 5

您可以std::tuple为此使用。它使您可以创建异构类型的对象,而不必指定所有样板。它确实有缺点。您不能给元组成员起名字。您必须通过它们的“索引”(第一个成员是索引0)或类型(仅当您不重复这些类型时才有效)来访问它们。所以

easy = {"keyframe_range":[], "value":0.25, "interpolation":"bezier"}
Run Code Online (Sandbox Code Playgroud)

会成为

auto easy = std::tuple<std::vector<int>, float, std::string>{{}, 0.25, "bezier"}
Run Code Online (Sandbox Code Playgroud)

回答:您可以像std::get<1>(easy)/ 那样访问成员std::get<float>(easy)以获取float成员。


C ++ 17:您可以使用结构化绑定来获取对类似成员的命名访问

auto&[easy_vec, easy_float, easy_string] = easy;
Run Code Online (Sandbox Code Playgroud)

现在easy_veceasy_floateasy_string是对元组成员的引用。