简体   繁体   English

如何在不创建构造函数的情况下使用私有/受保护成员初始化 POD 结构?

[英]How to initialize POD struct with private/protected members without creating constructor?

POD can have private/protected members POD 可以有私有/受保护的成员

Because of protected members, it is impossible to initialize struct like this:由于受保护的成员,不可能像这样初始化结构:

struct SomePOD_t {
protected:
    char *p_begin;
    char *p_end;
};

void foo() {
    const char *STR = "Some data";
    SomePOD_t data = { STR, STR + strlen(STR)+1 }; // error "no mathing constructor for
                                                   // initialization of SomePOD_t"
}

My question is how to make easier passing POD types to functions:我的问题是如何更轻松地将 POD 类型传递给函数:

// gonna use this foo
void foo_uses_some_pod(SomePOD_t data);

void foo()
{
     const char *STR = "Some data";

      //error "no matching function for call to 'foo_uses_some_pod'"
      // "candidate function not viable: cannot convert initializer list argument to 'SomePOD_t'"
     foo_uses_some_pod({STR, STR + strlen(STR)+1});

     //ok, if SomePOD_t::static_built_function is defined.
     foo_uses_some_pod(SomePOD_t::static_built_function(STR, STR + strlen(STR)+1)); 
}

I think explicit type mapping SomePOD_t{STR, STR + strlen(STR)+1} in the function call is a good practice, but excess static_built_function in SomePOD_t::static_built_function(STR, STR + strlen(STR)+1) is too much.我想明确的类型映射SomePOD_t{STR, STR + strlen(STR)+1}在函数调用是一个很好的做法,但过量static_built_functionSomePOD_t::static_built_function(STR, STR + strlen(STR)+1)实在是太多了.

If I add constructor to SomePOD_t it will not be POD anymore, so all types, that use SomePOD_t will become non-POD too and I have to add constructors for every type with SomePOD_t as member, or type with type that has type ... ... that has SomePOD_t as member.如果我向SomePOD_t添加构造SomePOD_t ,它将不再是 POD,所以所有使用SomePOD_t类型也将成为非 POD,我必须为每个类型添加构造函数,其中SomePOD_t作为成员,或者类型具有类型的类型... ...有SomePOD_t作为成员。

Can type be POD, have private/protected members and support initializer-list inititalization?类型可以是 POD,拥有私有/受保护成员并支持初始化列表初始化吗? How?如何?

Things have changed over time.随着时间的推移,事情发生了变化。 More recent specifications of the C++ language have deprecated the concept of a "POD" class. C++ 语言的最新规范已弃用“POD”类的概念。 There is now the idea of an "aggregate".现在有了“聚合”的概念。 Aggregates cannot have protected or private members, nor can they have non-default constructors.聚合不能有受保护或私有成员,也不能有非默认构造函数。 The initialization you are trying with an initializer list can be applied to aggregates.初始化您正在使用初始化列表尝试可应用于聚集。

Since you have protected members, aggregate initialization does not apply.由于您有受保护的成员,因此聚合初始化不适用。 If you want to construct the object with an initializer list you need to provide a constructor to do so.如果你想用初始化列表构造对象,你需要提供一个构造函数来这样做。

The requirements for POD class regarding constructors are:关于构造函数的POD 类的要求是:

  • Has one or more default constructors, all of which are either trivial or deleted, and at least one of which is not deleted.具有一个或多个默认构造函数,所有这些构造函数要么是平凡的要么被删除,并且至少有一个未被删除。

  • Every copy constructor is trivial or deleted每个复制构造函数都是微不足道的或被删除的

  • Every move constructor is trivial or deleted每个移动构造函数都是微不足道的或已删除

  • Every copy assignment operator is trivial or deleted每个复制赋值运算符都是微不足道的或被删除的

  • Every move assignment operator is trivial or deleted每个移动赋值运算符都是微不足道的或被删除的

  • at least one copy constructor, move constructor, copy assignment operator, or move assignment operator is non-deleted至少有一个复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符未被删除

Those restrictions are only on the special constructors listed above (namely default constructors and copy/move constructors).这些限制仅适用于上面列出的特殊构造函数(即默认构造函数和复制/移动构造函数)。 That said, you can have other user-defined constructors.也就是说,您可以拥有其他用户定义的构造函数。

Example:例子:

#include <iostream>
#include <type_traits>

struct SomePOD_t {
private:
    int a;
    int b;

public:
    // Note that "= default" is required here; 
    // otherwise the default constructor wouldn't be defined.
    SomePOD_t() = default;
    SomePOD_t(int a, int b) : a(a), b(b){}
};

void foo(SomePOD_t pod) { }

int main(int argc, char** args)
{
    std::cout << std::boolalpha;
    std::cout << std::is_pod<SomePOD_t>::value << std::endl; // true
    foo({1, 2});
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM