Background: I had something like (but with significant code in Z that I didn't want to change and the warning is enabled globally - I know I could disable it):
#pragma warning (error: 4355)
struct A;
struct B;
struct MapCompare {
A*the;
MapCompare(A*a):the(a) {;}
bool operator()(int,int) const;
};
class Z {
A a;
B b;
std::map<int,int,MapCompare> m;
public:
Z():m{MapCompare{&a}} {;}
...
};
But I want to change to use both a and b inside MapCompare. The less impactful variant seemed to be:
#pragma warning (error: 4355)
struct A;
struct B;
struct AB {
A a;
B b;
};
struct MapCompare {
AB*the;
MapCompare(AB*ab):the(ab) {;}
bool operator()(int,int) const;
};
class Z : public AB {
std::map<int,int,MapCompare> m;
public:
Z():m{MapCompare{static_cast<AB*>(this)}} {;}
...
};
The error message is:
error C4355: 'this': used in base member initializer list
So Visual Studio 2019 (16.9.5) complains about using this
in an initializer, even though I only want the base-part that is initialized (see Order of execution in constructor initialization list ).
Is there some way to tell this to the compiler (and not just disable the warning)? The work-around I found was:
#pragma warning (error: 4355)
struct A;
struct B;
struct AB {
A a;
B b;
};
struct MapCompare {
AB*the;
MapCompare(AB*ab):the(ab) {;}
bool operator()(int,int) const;
};
class Z {
AB ab;
A&a;
B&b;
std::map<int,int,MapCompare> m;
public:
Z():m{MapCompare{&ab}},a(ab.a),b(ab.b) {;}
...
};
Note: I tried to search for similar issues and found Initialize a reference - warning C4355: 'this' : used in base member initializer list but the difference is that I want to extract the base-class part that has been initialized which makes it safe (as long as the members are in this order).