views:

190

answers:

1

I have the following class hierarchy:

template <typename T>
class base
{
public:
   void f() {}
};

class class_a : public base<class_a> {};

class class_b : public base<class_b>, 
                public class_a 
{ 
   using base<class_b>::f; 
};

int main()
{
   class_b b;
   b.f();
   return 0;
}

Comeu and Intel C++ v11 claim all is well, however GCC (4.4.1) and VC++ 2008 seem to complain ( http://codepad.org/KQPDsqSp ), eg:

g++ -pedantic -Wall -o test test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:5: error: ‘void base<T>::f() [with T = class_b]’ is inaccessible
test.cpp:14: error: within this context 

I believe the code is well formed as it is, however I could be wrong, I'm hoping someone from the SO C++ community could provide some insight into this issue.

Note: Adding "public" before the using directive in class_b, resolves the issue for both gcc and VS. Should the accessor section of the class in which the using directive is applied override the derivation mode (public, private) of the base class?

In short is this

  • A compiler error - if so which compiler GCC,VS or Comeu,Intel
  • Is the above code well formed?
  • Does the accessor section in which a using directive is called override the derivation mode of the base?
+5  A: 

What you are doing here, is resolving an ambiguity by importing the symbol into the classes private namespace. Hence it's method shadowing and changing it's visibility to private. You can't have two functions with the exact same prototype both private and public, hence the f is now private.

At least GCC believes that using should be able to change the visibility of a function.

Vague references however found in GCC bug database, show that using in fact shouldn't be affected by scope.

Most importantly, a direct answer (C++ Standard '03 -- 7.3.3/15)

The alias created by the using-declaration has the usual accessibility for a member-declaration.

Hence the answers would be:

  • it's a bug in Comeau
  • no, the code is not well formed, at least C++03-wise (can't find anything related in C++0x N3000)
  • yes, you can change access scope
Kornel Kisielewicz
Nothing is in a private namespace or scope. and the using directive does not consider the accessor portion of the class in which it is called - however adding public before the using directive does resolve the issue. I believe in this case gcc and VS are at fault, don't you think?
dman
@darid, in the link provided above you'll see that at least in GCC's case it was changed to the way it is now explicitly.
Kornel Kisielewicz
@Kornel: thats an excellent answer, I'd like to add I've tried it with the intel c++ compiler and it likes it like Comeau does. I wonder if its a parser interface issue, intel and Comeau get theirs from EDG, but so does MS for VSC++, which just confuses things all that more.
dman
@darid, ok, found a direct reference in 7.3.3/15 :)
Kornel Kisielewicz
@Kornel: excellent thanks! - btw who would have ever thought Comeau could have a bug! :D
dman
@darid: MSVC doesn't use EDG's parser for the compiler. I believe they're using it for intellisense in VS10, but the compiler itself uses their own crufty old parser.
jalf