2017-02-26 30 views
0

我不能修改庫的構件陣列的具有類型類似於以下:初始化不可複製的,非可移動的,明確地構造類型

class A { 
    public: 
    A() : A(0) { } 
    explicit A (int const value) : value_(value) { } 

    A (A const &) = delete; 
    A (A &&) = delete; 

    A & operator= (A const &) = delete; 
    A & operator= (A &&) = delete; 

    private: 
    int value_; 
} 

現在,我有這需要一個類一堆A作爲成員。由於環境的其他限制,我在所有這些工作A必須是單獨的成員或成員數組(即我不能使用std::vector將它們放入或創建指針)。即我的課歸結爲:

struct Foo { 
    A a[2]; 
} 

是否有任何方法來初始化每個成員具有不同的初始值?我一直在嘗試使用加載列表初始化的各種形式,但是由於A(int)是顯式的或者A沒有複製/移動構造函數,所以它們全部失敗。

什麼不起作用:

  • Foo() : A{ { 1 }, { 2 } } { }:不會叫A(int)因爲它是explicit
  • Foo() : A{ { A(1) }, { A(2) } } { }:無法複製或移動分配。

編輯:有關成員數組要求的更新信息。

編輯2:有問題的庫是SystemC。我的示例類A是一個端口(例如sc_core::sc_in)。

我不能使用指針數組的原因是,據我所知,Mentor Graphic's Questa不能真正處理它們。它將正確模擬模型,但不允許檢查端口。即它將無法在波形窗口中隨時間繪製端口值。我很可能會被證明是錯誤的,因爲這樣可以解決我的問題。

編輯3:顯然這是Questa新版本中的一個大問題。我不確定在看到這個問題和現在之間有什麼變化,也可能是對開發環境的改變(這也是我無法控制的)。無論如何,我的Questa現在會自動將變量名稱命名爲端口(除非在構造時明確重命名),所以一切都很好。

只是爲了知道如何我仍然希望看到原始問題的潛在解決方案。

+0

爲什麼不寫一個循環來分配堆棧中的每個A並初始化每個值? – vincent

+2

你必須要問你爲什麼在你的代碼中設置了所有這些限制。 –

+0

@vincent我剛剛更新了我的問題。小故事:不允許在堆棧上創建「A」。長篇故事:代碼用於外部公司編寫的「類似調試器」的工具,該工具無法處理指針成員的檢查。 – Darhuuk

回答

0

簡短的回答 - 沒有。較長的答案 - 種類,但它的噁心。

看看this的討論。

1
struct Foo { 
    A a[2]; 
} 

是否有任何方式給每個成員初始化與不同的初始值 ?我一直在嘗試各種形式的使用加載列表 初始化,但它們全都失敗,因爲A(int)是 explicit或A沒有複製/移動構造函數。

您可能需要使用投放新在一些原始存儲陣列創建的A數組。然後,您創建構建每個A所需的std::initializer_list<ARGUMENT>ARGUMENT。喜歡的東西:

template<typename T, std::size_t Size, std::size_t Alignment = alignof(T)> 
struct FixedArray{ 
    std::aligned_storage_t<sizeof(T), Alignment> data[Size]; 

    static constexpr std::size_t size = Size; 

    template<typename U> 
    FixedArray(std::initializer_list<U> ls){ 
     assert(ls.size() <= Size && "Invalid Size"); int index = 0; 
     for(auto& x : ls) 
      new (&data[index++]) T(x); 
    } 

    FixedArray(const FixedArray&) = delete; 
    FixedArray(FixedArray&&) = delete; 

    A& operator[](std::size_t index){ 
     auto ptr = reinterpret_cast<A*>(&data) + index; 
     return *std::launder(ptr);   //Sort of a legal way to alias memory C++17 
    } 

    ~FixedArray(){ 
     for(std::size_t i = 0; i < size; i++) 
      this->operator[](i).~T(); 
    } 

}; 

然後聲明符:

struct Foo { 
    FixedArray<A, 4> a; 
}; 

要創建FooA(546)A(99)A(-4)A(0)

int main() { 
    Foo f{{546, 99, -4, 0}}; 
    return 0; 
} 

見工作Demo


-O3優化級別與GCC 6.3測試,約完全相同的組件後使用FixedArray VS普通原陣列,參見它gcc.godbolt.com被生成。

+0

整潔。恐怕該工具不支持它,但值得一試。 – Darhuuk

相關問題