I would like to know why the following code does not compile:
class base {
protected:
typedef void (base::*function_type)() const;
void function_impl() const {} // error: ‘void base::function_impl() const’ is protected
};
class derived: public base {
public:
operator function_type() const {
return boolean_test() == true ? &base::function_impl : 0; // error: within this context
}
protected:
virtual bool boolean_test() const = 0;
virtual ~derived() {}
};
int main(int argc, char* argv[]) {
}
g++
output:
~/protected_test$ g++ src/protected_test.cpp
src/protected_test.cpp: In member function ‘derived::operator base::function_type() const’:
src/protected_test.cpp:4:8: error: ‘void base::function_impl() const’ is protected
src/protected_test.cpp:10:44: error: within this context
This code was adapted from here and I see no one complaining about that at the discussion forum. Also, I'm using g++ 4.7.2 and the same code compiles and links fine with egcs-2.91.66.
The specification of protected access states that pointer to members have to be formed either through the derived type (i.e. derived::...
) or a type inherited from it. You can't name function_impl
directly through base
.
That means that in your case you have to do it as
operator function_type() const {
return boolean_test() == true ? &derived::function_impl : 0;
}
Note that even if you use &derived::function_impl
expression to obtain the address, the type of the result is still void (base::*function_type)() const
, since the name function_impl
in this case resolves to the function of base
class.
If it used to compile in some specific compiler (or some specific version of it), it simply means that that compiler allowed the error to slip through, which is what probably explains the code at the link.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With