c++constructorc++20aggregate-initialization

Give an aggregate a converting constructor?


I'm writing a large fixed-size integer type that is made up of multiple uint64_ts, like in the (simplified) example below. I would like my type to behave like the built-in integer types, which means (among other things) that:

  1. it should be uninitialized if you don't assign a value to it, and
  2. it should accept widening from other built-in integer types.

It appears to me, however, that one cannot write a type that simultaneously satisfies both properties. This is because property 1 requires the type to be an aggregate, which means it must have no constructors, and we need a constructor to implement property 2.

Is there any way to write a large integer type that satisfies both properties?

#include <array>
#include <cstdint>

struct uint128_t{
    std::array<uint64_t, 2> data;
};

int main(){
    uint128_t x; // uninitialized (good)
    uint128_t y = 100; // can we make this work while ensuring that the previous line still works?
}

Solution

  • A constructor such as uint128_t() {} will leave your array uninitialized by default. Ability to leave members uninitalized has nothing to do with being an aggregate.

    But there's a better option: uint128() = default;. It will cause uint128_t x; to be uninitialized, but uint128_t x{}; will be zeroed, just like with built-in types.