Bug 102590 - structured binding inside for all loop thinks it is type depedent when it is not (inside a template)
Summary: structured binding inside for all loop thinks it is type depedent when it is ...
Status: RESOLVED DUPLICATE of bug 84469
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2021-10-04 11:06 UTC by Rajat Jain
Modified: 2021-10-05 05:43 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-10-05 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rajat Jain 2021-10-04 11:06:02 UTC
Foreach loops written with a structured-binding declaration error out if any of the captured types contains a template member-function which is used inside the loop.

This only happens if such a loop is placed inside a templated lambda/function.

A minimal example of the above is:

struct Foo
{
    template<typename T>
    T get() const
    {
        return static_cast<T>(0);
    }
};

template<typename T>
void error_func(T elem)
{
    std::array<std::pair<int, Foo>, 1> arr;
    for(const auto& [_, val] : arr)
    {
        val.get<int>(); // Error here
    }
}

The error disappears if T is replaced with any concrete type. It also disappears if instead of structured bindings, a tuple is used with auto type specifier.

The above code also works if one writes:

const auto& [_, val] = arr[0];
val.get<int>();

Compilation flags: -std=c++17

Reported error:

test.cpp:19:17: error: expected primary-expression before 'int'
         val.get<int>();
                 ^~~
test.cpp:19:17: error: expected ';' before 'int'
         val.get<int>();
                 ^~~
                 ;
Comment 1 Andrew Pinski 2021-10-04 11:14:01 UTC
My bet is gcc mistaken it for being a dependent type which meaning you can use the template keyword to workaround the issue. Also gcc 8.x series is over 3 years old so this might be fixed already in a newer version of gcc.
Comment 2 Rajat Jain 2021-10-04 11:31:48 UTC
Yeah .template works as well. This is in the latest release too. I wasn't sure whether I should write the oldest version that this is in (since other 8.x releases would need a patch as well), or the latest. Let me change that.
Comment 3 Andrew Pinski 2021-10-05 05:41:42 UTC
Reduced testcase (without any includes):
struct Foo
{
    template<class T> T get() const { return 0;  }
};

struct f
{
  int t;
  Foo t1;
};

template<typename T>
void error_func(T elem)
{
    f arr[1];
    for(const auto& [_, val] : arr)
    {
        val.get<int>(); // Error here
    }
}
Comment 4 Andrew Pinski 2021-10-05 05:43:25 UTC
Dup of bug 84469.

*** This bug has been marked as a duplicate of bug 84469 ***