web-dev-qa-db-ja.com

構造化バインディングが構造体で期待どおりに機能しないのはなぜですか?

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

構造化バインディングが構造体で期待どおりに機能しないのはなぜですか?

13
xmllmx

これは既知のバグです。 https://bugs.llvm.org/show_bug.cgi?id=33236 を参照してください。

基本的に、問題は、記述されているC++ 17標準では、構造化バインディング宣言がTをタプルのような型として扱い、_std::Tuple_size<T>::value_が定義されている場合は常に_std::Tuple_size<T>_を使用することを指定しています。ただし、標準ライブラリがすべてのconstタイプTに対して_std::Tuple_size<T>_を定義することも指定します。

つまり、_const auto&[r3, r4] = x;_をコンパイルするときに、Clangは_std::Tuple_size<const X>_を探し、標準ライブラリ(MSVCによって提供される)で定義を見つけます。 _std::Tuple_size<const X>_の定義が正常に検出されたため、Clangは「タプルのような」バインディングプロトコルを使用しようとしますが、十分に失敗します。_const X_はタプルのようなものではありません。

MSVC STLメンテナからの提案( ソース ):

回避策:構造体でconstを使用しないでください。

7
cpplearner