2017-02-26 72 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