How to use concepts to retrieve the number of fields in a class?

Viewed 74

I had the bright idea that I could use concepts and structured bindings to figure out the number of fields in a struct and then dispatch based on this. The code we came up with is

#include <iostream>
#include <concepts>

template <typename T>
concept HasOneMember = requires (T const & t) {
    [](T t){
        auto [a]=t;
        return 0;
    }(t);
};


template <typename T>
concept HasTwoMember = requires (T const & t) {
    [](T t){
        auto [a,b]=t;
        return 0;
    }(t);
};


template <typename T> requires HasOneMember<T>
auto foo(T t)
{
    auto & [a]=t;
    std::cout << "has one member " << a <<  std::endl;
}

template <typename T> requires HasTwoMember<T>
auto foo(T t)
{
    auto & [a,b]=t;
    std::cout << "has not one member "<< a << " " << b << std::endl;
}


int main(){
    struct One {
        int a;
    };
    struct Two {
        int b;
        int c;
    };

    foo(One{7});
    foo(Two{42, 8});
}

For clang this works

has one member 7
has not one member 42 8

is the output. However for gcc this does not.

https://godbolt.org/z/vdq6Koezc

I'm curious. Is this because the code is illegal and should not work or does GCC have a bug?

Maybe it is possible to tweak the code so it works in GCC also?

It also compiles for MSVC.

0 Answers
Related