Initialization of member array of non-copyable, non-movable, explicitly constructed types

前端 未结 3 936
滥情空心
滥情空心 2020-12-21 06:16

A library which I can\'t modify has a type akin to the following:

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


        
相关标签:
3条回答
  • 2020-12-21 06:35
    struct Foo {
      A a[2];
    }
    

    Is there any way to initialize each member with a distinct initial value? I've been trying various forms of using braced-list initialization, but they all fail due to either A(int) being explicit or A not having a copy/move-constructor.

    You may need to use placement-new to create an array of A in some raw storage array. You then create a std::initializer_list<ARGUMENT> of the ARGUMENTs needed to construct each A. Something like:

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

    Then declare Foo:

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

    To create Foo having A(546), A(99), A(-4), A(0):

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

    See a working Demo


    After testing with GCC 6.3 at -O3 optimization levels, about exactly the same assembly is generated for using FixedArray vs plain raw arrays, See it on gcc.godbolt.com.

    0 讨论(0)
  • 2020-12-21 06:40

    I am able to solve the problem as follows (also using SystemC, here my non-copyable, non-movable items are sc_modules):

    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"}}}
        {}
    };
    
    0 讨论(0)
  • 2020-12-21 06:57

    The short answer - no. The longer answer - kind of, but its disgusting.

    Take a look at this discussion.

    0 讨论(0)
提交回复
热议问题