Почему структурированное связывание не работает должным образом на 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 (в Windows) сообщение об ошибке:

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

Почему структурированное связывание не работает должным образом на struct?

Ответ 1

Это известная ошибка. Смотрите https://bugs.llvm.org/show_bug.cgi?id=33236.

По сути, проблема в том, что стандарт С++ 17 в том виде, в котором он написан, определяет, что объявление структурированной привязки обрабатывает T как тип, подобный кортежу, и использует std::tuple_size<T>::value всякий раз, когда определяется std::tuple_size<T>; но также указывает, что стандартная библиотека определяет std::tuple_size<T> для всех константных типов T.

Это означает, что при компиляции const auto&[r3, r4] = x; Clang ищет std::tuple_size<const X> и находит определение в стандартной библиотеке (которая предоставляется MSVC). Поскольку определение std::tuple_size<const X> успешно найдено, Clang пытается использовать протокол связывания типа "кортеж", и он, безусловно, терпит неудачу: const X не похож на кортеж!

Предложение от сопровождающего MSVC STL (источник):

Обходной путь: не используйте const в структуре.