将std :: array <char,10>的最后一个字符转换为int

Kyu*_*u96 1 c++ memory arrays int char

给定以下数组:std::array<char, 10> stuff我想将最后4个字符转换为相应的int32值。

我尝试对最后一项进行OR操作的链接,但似乎不是正确的方法:

int a = int(stuff[6] | stuff[7] | stuff[8] | stuff[9])

有解决这个问题的优雅方法吗?

chr*_*ris 5

您尝试执行的操作具有高雅性,无需进行字节序检查即可正常工作。您错过的是一些转移,以表明最终价值的重要性:

int a = stuff[6] << 24 | stuff[7] << 16 | stuff[8] << 8 | stuff[9];
Run Code Online (Sandbox Code Playgroud)

仅此一点并不关心字节顺序,因为从语言的角度来看,它基于值而不是字节。您确定哪些值最重要。

就是说,这还假设一个8位字节和至少4字节int。如果您想要优雅的使用,可以通过安全且通用的抽象来获得:

#include <array>
#include <climits>
#include <cstddef>

namespace detail {
    // Could be replaced by an inline lambda-template in C++20.
    template<typename T, std::size_t N, std::size_t... Is>
    constexpr T pack_into_impl(const std::array<std::byte, N>& bytes, std::index_sequence<Is...>) {
        // Build final value from right to left to make the math more clear 
        // and to use the least significant bytes available when N < sizeof(T).
        // e.g., bytes[3] << 0 | bytes[2] << 8 | bytes[1] << 16 | bytes[0] << 24
        return ((static_cast<int>(bytes[N-Is-1]) << (CHAR_BIT * Is)) | ...);
    }
}

// Takes bytes to pack from most significant to least significant.
// N.B. this is not a production-ready doc comment for this function.
template<typename T, std::size_t N>
constexpr T pack_into(std::array<std::byte, N> bytes) {
    static_assert(sizeof(T) >= N, "Destination type is too small for this many bytes");
    return detail::pack_into_impl<T>(bytes, std::make_index_sequence<N>{});
}

// Convenience overload.
template<typename T, typename... Bytes>
constexpr T pack_into(Bytes... bytes) {
    // Check that each Bytes type can be static_cast to std::byte.
    // Maybe check that values fit within a byte.
    return pack_into<T>(std::array{static_cast<std::byte>(bytes)...});
}

int main() {
    static_assert(pack_into<int>(0x12, 0x34, 0x56, 0x78) == 0x12345678);
    static_assert(pack_into<int>(0x01, 0x02) == 0x0102);
    // pack_into<int>(0x01, 0x02, 0x03, 0x04, 0x05); // static_assert
}
Run Code Online (Sandbox Code Playgroud)

在C ++ 20中,可以使用概念和[]<std::size_t... Is>lambda 清理其中的某些内容,但是您知道了。当然,为了方便起见,您也可以自由地转换API以使其大小未知,以方便使用,并且在给出太多字节时可以进行运行时检查。这取决于您的用例。