c++bytec++20literalsuniform-initialization

how do I declare and initialize an array of bytes in C++


Is this really the best way to declare a byte (or array of bytes)?

static constexpr byte kGuard1_[] = {
            byte{0x45}, byte{0x23}, byte{0x12}, byte{0x56}, byte{0x99}, byte{0x76}, byte{0x12}, byte{0x55},
        };

why isn't there some suffix (like b) that you can use to directly mark the number as a byte? Or is the problem just with my use of uniform initialization?


Solution

  • I can't say if this is better but it's different since you won't have to repeat byte for every element:

    #include <array>
    #include <utility>
    
    template <class T, class... Args>
    constexpr auto mkarr(Args&&... args) {
        return std::array{static_cast<T>(std::forward<Args>(args))...};
    }
    
    static constexpr auto kGuard1 = mkarr<std::byte>(0x45, 0x23, 0x12, 0x56,
                                                     0x99, 0x76, 0x12, 0x55);
    

    Note that it uses a std::array<std::byte, 8> instead of a std::byte[8].


    why isn't there some suffix (like b) that you can use to directly mark the number as a byte?

    I can't say, but if you want you can define your own user-defined literal that could be used with C arrays.

    constexpr std::byte operator""_B(unsigned long long x) {
        // note: no space between "" and _B above
        return static_cast<std::byte>(x); 
    }
    
    static constexpr std::byte kGuard1[]{0x45_B, 0x23_B, 0x12_B, 0x56_B,
                                         0x99_B, 0x76_B, 0x12_B, 0x55_B};
    

    Or is the problem just with my use of uniform initialization?

    No, it's just that there is no implicit conversion to std::byte.