struct Base {
void func(int n) {}
};
struct Derived : Base {
public:
template<class T>
void func(T const& p) {
Base::func(20);
}
private:
using Base::func;
};
int main(int, char*[]) {
Derived d;
float f(5.f);
d.func(f);
}
// Build log:
1>------ Build started: Project: testing, Configuration: Debug Win32 ------
1>Compiling...
1>main.cpp
1>z:\my c++ projects\testing\testing\main.cpp(616) : warning C4100: 'n' : unreferenced formal parameter
1>z:\my c++ projects\testing\testing\main.cpp(637) : error C2248: 'Derived::func' : cannot access private member declared in class 'Derived'
1> z:\my c++ projects\testing\testing\main.cpp(628) : see declaration of 'Derived::func'
1> z:\my c++ projects\testing\testing\main.cpp(619) : see declaration of 'Derived'
1>Build log was saved at "file://z:\My C++ Projects\testing\testing\Debug\BuildLog.htm"
1>testing - 1 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
🎉 Celebrating 25 Years of GameDev.net! 🎉
Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!
C++ base member access control
Just curious as to why this doesn't compile (Visual Studio 2008):
If I shift the derived function declaration below the using Base::func; it works ok. Is this a compiler bug?
Well, this is a simplified example, but I don't actually want it to be virtual... I understand that the base version will be hidden by the derived version, but shouldn't this still work?
GCC (well MinGW - not sure what version I have installed) compiles it ok.
GCC (well MinGW - not sure what version I have installed) compiles it ok.
The using shouldn't be private, it should be public.
That's also what the compiler is saying.
That's also what the compiler is saying.
Quote: Original post by _fastcall
Base::func needs to be virtual. Other than that, the code's ok.
I don't think this has anything to do with virtual functions. It's about overload resolution.
Quote: Original post by delta user
The using shouldn't be private, it should be public.
That's also what the compiler is saying.
It's absolutely legal for to have private using declarations. There's nothing wrong with that.
The problem appears to be that VC++ is looking at both func methods in order to do overload resolution. As one of them is private, there's an access violation and compilation fails. I *think* this is correct. I'll try to find a reference.
Quote: Original post by sprite_hound
If I shift the derived function declaration below the using Base::func; it works ok. Is this a compiler bug?
There's probably a bug in g++ and/or VC++ but I wouldn't like to say which :)
EDIT: To clarify, I would expect that a conforming compiler would fail to compile the code regardless of the order in which the using directive and the func template are placed with respect to one another (as long as one of them is private in Derived).
EDIT 2: based on this article I have revised my opinion. Overload resolution occurs before access control. The best match for d.func(0.5f) is the templated member function. It's public so that should be allowed.
So I think g++ is correct and VC++ is wrong. Indeed, if you call d.func(1) instead, g++ fails to compile which is at least consistent with this logic.
[Edited by - the_edd on May 12, 2010 5:01:48 PM]
I must agree with a private using being valid, but i believe it wasn't meant to be private in this case.
It is annoying that VS is giving an error because it might be your intention to make it private.
On g++ on the other hand, the code compiles fine and runs the template function instead of the base function, which might not be what you intended.
It is annoying that VS is giving an error because it might be your intention to make it private.
On g++ on the other hand, the code compiles fine and runs the template function instead of the base function, which might not be what you intended.
Yeah, I want the base function to be private, and the template derived function to be public. VC++ seems to make both versions private with the using directive first.
the_edd, thanks for the article I didn't realise access control was considered afterwards.
the_edd, thanks for the article I didn't realise access control was considered afterwards.
I understand the problem with Visual Studio, but I'm wondering why use that method rather than this one?
Making the base class's function protected seems to give you everything your looking for.
struct Base {protected: void func(int n) {}};struct Derived : Base {public: template<class T> void func(T const& p) { Base::func(20); }};
Making the base class's function protected seems to give you everything your looking for.
Quote: Original post by adam23
I understand the problem with Visual Studio, but I'm wondering why use that method rather than this one?
*** Source Snippet Removed ***
Making the base class's function protected seems to give you everything your looking for.
I don't think sprite_hound has actually said what they're looking for :) I'm guessing by the nondescript names in the code ("Base", "Derived", "func") that the example has been simmered down from real-world code to illustrate the problem.
But I'll bite; what advantage does your code provide? There's still the same snag with access violation.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement