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.