簡體   English   中英

如何在不創建構造函數的情況下使用私有/受保護成員初始化 POD 結構?

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

POD 可以有私有/受保護的成員

由於受保護的成員,不可能像這樣初始化結構:

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"
}

我的問題是如何更輕松地將 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)); 
}

我想明確的類型映射SomePOD_t{STR, STR + strlen(STR)+1}在函數調用是一個很好的做法,但過量static_built_functionSomePOD_t::static_built_function(STR, STR + strlen(STR)+1)實在是太多了.

如果我向SomePOD_t添加構造SomePOD_t ,它將不再是 POD,所以所有使用SomePOD_t類型也將成為非 POD,我必須為每個類型添加構造函數,其中SomePOD_t作為成員,或者類型具有類型的類型... ...有SomePOD_t作為成員。

類型可以是 POD,擁有私有/受保護成員並支持初始化列表初始化嗎? 如何?

隨着時間的推移,事情發生了變化。 C++ 語言的最新規范已棄用“POD”類的概念。 現在有了“聚合”的概念。 聚合不能有受保護或私有成員,也不能有非默認構造函數。 初始化您正在使用初始化列表嘗試可應用於聚集。

由於您有受保護的成員,因此聚合初始化不適用。 如果你想用初始化列表構造對象,你需要提供一個構造函數來這樣做。

關於構造函數的POD 類的要求是:

  • 具有一個或多個默認構造函數,所有這些構造函數要么是平凡的要么被刪除,並且至少有一個未被刪除。

  • 每個復制構造函數都是微不足道的或被刪除的

  • 每個移動構造函數都是微不足道的或已刪除

  • 每個復制賦值運算符都是微不足道的或被刪除的

  • 每個移動賦值運算符都是微不足道的或被刪除的

  • 至少有一個復制構造函數、移動構造函數、復制賦值運算符或移動賦值運算符未被刪除

這些限制僅適用於上面列出的特殊構造函數(即默認構造函數和復制/移動構造函數)。 也就是說,您可以擁有其他用戶定義的構造函數。

例子:

#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