代码之家  ›  专栏  ›  技术社区  ›  Nicholas Wilson

如何在数组初始化器列表中初始化显式构造函数?[副本]

  •  1
  • Nicholas Wilson  · 技术社区  · 6 年前

    我无法修改的库的类型类似于:

    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 s必须是单独的成员或成员数组(即,我不能使用 std::vector 将它们放入或创建指向它们的指针)。一、 e.我的课可以归结为:

    struct Foo {
      A a[2];
    }
    

    有没有办法用不同的初始值初始化每个成员?我一直在尝试各种形式的使用大括号列表初始化,但是它们都失败了 A(int) 明确的或 A 没有复制/移动构造函数。

    什么不起作用:

    • Foo () : A{ { 1 }, { 2 } } { } :不打电话 A(内景) 因为它是 explicit .
    • Foo () : A{ { A(1) }, { A(2) } } { }

    编辑: 有关成员数组要求的更新信息。

    有问题的图书馆是 SystemC . 我的示例类 A 是一个端口(例如。 sc_core::sc_in ).

    我不能使用指针数组的原因是,据我所知, Mentor Graphic's Questa 真的不能对付他们。它将正确模拟模型,但不允许检查端口。一、 它将无法在波形窗口中绘制端口值随时间的变化。我很可能会被证明是错误的,因为这将允许一个微不足道的解决我的问题。

    编辑3: 显然,这在新版本的Questa中已经不再是一个大问题了。我不确定从看到这个问题到现在发生了什么变化,可能是开发环境也发生了变化(这也超出了我的控制范围)。在任何情况下,我的Questa现在都会自动以变量名命名端口(除非在构建时显式重命名),所以一切正常。

    不过,为了知道如何解决这个问题,我还是希望看到原始问题的潜在解决方案。

    0 回复  |  直到 8 年前
        1
  •  2
  •   WhiZTiM    8 年前
    struct Foo {
      A a[2];
    }
    

    有没有办法用不同的初始值初始化每个成员 价值?我一直在尝试使用大括号列表的各种形式 A(int) 存在 显式或 A

    您可能需要使用 新位置 创建 A std::initializer_list<ARGUMENT> ARGUMENT 每个都需要 A . 比如:

    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();
        }
    
    };
    

    然后声明Foo:

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

    创造 Foo A(546) , A(99) , A(-4) A(0) :

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

    Demo


    按照GCC 6.3进行试验后 -O3 优化级别,生成的程序集与使用的程序集完全相同 FixedArray 与普通原始数组相比,请参见 gcc.godbolt.com .

        2
  •  1
  •   sheridp    6 年前

    class Object : sc_module {
        Object(sc_module_name name){}
    };
    
    class Container : sc_module {
    
        std::array<Object, 3> objects;
    
        Container(sc_module_name name) :
        objects{{{"object1"},{"object2"},{"object3"}}}
        {}
    };
    
        3
  •  0
  •   Community CDub    8 年前

    简短的回答-不。较长的回答-有点,但很恶心。

    看一看 this 讨论。