Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does structured binding not work as expected on struct?

struct X { int a, b; };

int main()
{
    auto p = std::pair{ 1, 2 };
    const auto&[r1, r2] = p; // ok

    X x{ 1, 2 };
    const auto&[r3, r4] = x; // error
}

clang 7.0 (on Windows) 's error message:

error : cannot decompose this type; 'std::tuple_size<const X>::value' is not a valid 
           integral constant expression

Why does structured binding not work as expected on struct?

like image 282
xmllmx Avatar asked Dec 11 '18 10:12

xmllmx


1 Answers

This is a known bug. See https://bugs.llvm.org/show_bug.cgi?id=33236.

Basically, the problem is, the C++17 standard as written specifies that structured binding declaration treats T as a tuple-like type and uses std::tuple_size<T>::value whenever std::tuple_size<T> is defined; but it also specifies that the standard library defines std::tuple_size<T> for all const type T.

That means, when compiling const auto&[r3, r4] = x;, Clang looks for std::tuple_size<const X>, and finds the definition in the standard library (which is provided by MSVC). Since the definition of std::tuple_size<const X> is successfully found, Clang attempts to use the "tuple-like" binding protocol, and it sure enough fails: const X is nothing like a tuple!

Suggestion from MSVC STL maintainer (source):

Workaround: don’t use const on the struct.

like image 141
cpplearner Avatar answered Oct 11 '22 11:10

cpplearner