This compiles on Clang and GCC, but not MSVC:
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <array>
template <uint32_t N>
struct BitfieldBits
{
constexpr static inline uint64_t num_bits = N;
};
struct DepthMode : BitfieldBits<2>
{};
struct UseCulling : BitfieldBits<1>
{};
struct VertexShaderID : BitfieldBits<8>
{};
template <typename ... T>
struct MyBitfield
{
uint64_t bitfield;
static inline std::tuple<T...> tuple;
constexpr static inline std::array<uint32_t, sizeof ... (T)> bit_shift_offsets = [](const std::tuple<T...>& tuple) consteval
{
constexpr uint32_t tuple_size = std::tuple_size_v<std::tuple<T...>>;
std::array<uint32_t, tuple_size> arr;
uint32_t bit_offset = 0;
for (size_t i = 0; i < tuple_size; ++i)
{
arr[i] = bit_offset;
// HERE MSVC DOESN'T COMPILE
bit_offset += std::get<i>(tuple).num_bits;
}
return arr;
}(std::tuple<T...>());
};
int main(int argc, char* argv[])
{
MyBitfield<DepthMode, UseCulling, VertexShaderID> my_bitfield;
}
Here is the Godbolt link showing all three compilers.
And the error message given by MSVC is:
error C2672: 'get': no matching overloaded function found
my_bitfield.bit_shift_offsetsalways failed though.