call of inherited protected sub-type in lambda function g++-4.8

70 Views Asked by At

In the following code, compilations fail from g++4.1 to 4.9. The "bug" seems having been corrected from g++-5.1. I tried under gcc.godbolt.org with -std=c++11 compilation flag.

#include <algorithm>
#include <vector>

class A 
{
protected:
    struct S
    {
        int a;
        int b;
    };
};

class B : public A
{
    std::vector<A::S> v;

public:
    void foo(std::vector<A::S> v)
    {
        std::sort(v.begin(), v.end(),
                [](const A::S& a,       // <--- error only here !
                   const A::S& b) { return a.a < b.b; });
    }

    void auto_sort()
    {
        foo(this->v);
    }
};

int main()
{
    B b;
    b.auto_sort();

    return 1;
}

The returned error is : 'struct A::S' is protected It appears only in the lambda function declaration.

My question is: was it a bug in g++-4.X ? and thus could it be corrected ? or is it a c++ rule that changed since g++-5.1 ? Or did I miss something ?

Do I have to write the lambda function as a method of B passed as argument ?

Of course, my goal is having a code compiling under any g++ version.

Thank you,

1

There are 1 best solutions below

0
StoryTeller - Unslander Monica On BEST ANSWER

This is a GCC bug (since fixed), related to how the access specifiers were checked on the lambda. The code is valid C++11. As a workaround you can just move the A::S access to a place where the protected specifier is guaranteed to be checked appropriately. It can be done by introducing a type alias:

using T = A::S;
std::sort(v.begin(), v.end(),
        [](const T& a,       
           const T& b) { return a.a < b.b; });

Live