While compiling the following (reduced) code:
#include <tuple>
#include <stdlib.h>
template<size_t N> struct tying;
template<> struct tying<1> {static auto function(auto& o) -> decltype(auto) {auto& [p1] = o;return std::tie(p1);}};
template<> struct tying<2> {static auto function(auto& o) -> decltype(auto) {auto& [p1,p2] = o;return std::tie(p1,p2);}};
template<typename T, size_t N> concept bool n_components =
requires(T& object) {
{ tying<N>::function(object) };
};
typedef struct
{
int a;
float b;
} test_t;
int main(int argc, char* argv[])
{
constexpr size_t n = 1;
constexpr bool t = n_components<test_t, n>;
printf("n_components<test_t, %d>: %s\n", n, t ? "yes" : "nope");
return 0;
}
with gcc specific options -std=c++1z -fconcepts
the gcc (version 7.3.0, and x86-64 gcc-trunk at godbolt also) fails with an error:
error: only 1 name provided for structured binding
note: while 'test_t' decomposes into 2 elements
I was very surprised by this, as the error "raises" inside the requires-expression
, and to my understanding, this should result in n_components
constraint to get evaluated to false, as the requirement is not satisfied.
Note: replacing constexpr size_t n = 1;
with other values "fixes" the error, so I presume the n_components
constraint is not to blame:
- replacing with
n = 2
then_components
constraint evaluates to "true" as expected. - replacing with
n = 3
then_components
constraint evaluates to "false" as expected - due to referring to unspecializedtying<3>
struct.
It seems there are no other compilers supporting the c++ concepts and structured bindings available yet to compare with.
PS. I was playing around with "poor man's reflection" a.k.a. magic_get
and hoped to replace the unreliable is_braces_constructible
trait with something more robust...