Import nested classes into namespace - C++
Asked Answered
S

3

25

Say I have a class like this:

class A {
public:
    class B {
        // ...
    };
    static void f();
    // ...
};

I can refer to B as A::B and to f() as A::f(), but can I import B and f() into the global/current namespace? I tried

using A::B;

but that gave me a compilation error.

Selima answered 25/7, 2012 at 10:7 Comment(3)
Was the compilation error, "error: ‘A’ is not a namespace"?Stair
You cannot do that for A::f().Nd
@Nd but you can achieve that behavior with a workaround.Tullis
M
19

You should be able to use namespace aliases for the class:

using B = A::B;

However you can't do that with the member function, not even with static member functions.

Edit: According to this SO answer (What is the difference between 'typedef' and 'using' in C++11) this should be valid, and actually creates a type alias in the same way that typedef does. However, it's C++11 only.


There is a workaround for static member functions in C++11, by declaring a variable pointing to the static function:

struct Foo
{
    static void bar()
        { }
};

auto bar = Foo::bar;

Edit: Of course, having a global variable pointing to a static member function is possible in the older C++ standard as well, but it's more messy than using the auto keyword of C++11. In the example above it would be:

void (*bar)() = Foo::bar;
Morton answered 25/7, 2012 at 10:41 Comment(4)
using B = A::B; this will not work. Another point is that function pointers cannot be inlined.Calorifacient
@SergeyK. Works fine for me, with GCC 4.7.1. But you're right about the inlining.Morton
1.cpp:9:7: error: expected nested-name-specifier before 'B' using B = A::B; (gcc.EXE (GCC) 4.8.0)Calorifacient
@SergeyK. Actually, the using keyword syntax is legal in C++11. When compiling with GCC did you use the -std=c++11 or -std=c++0x flags?Morton
C
33

Here are two workarounds for your problem:

1) Class B:

typedef A::B B;

2) Function f():

inline void f()
{
    A::f();
}

But think twice before using them.

Edit: In C++11 you can do auto f = A::f; but this actually creates a pointer to a function and functions pointers cannot be inlined.

Calorifacient answered 25/7, 2012 at 10:35 Comment(1)
For the typedefor using solutions, any idea to make it work even with private nested class?Sharice
M
19

You should be able to use namespace aliases for the class:

using B = A::B;

However you can't do that with the member function, not even with static member functions.

Edit: According to this SO answer (What is the difference between 'typedef' and 'using' in C++11) this should be valid, and actually creates a type alias in the same way that typedef does. However, it's C++11 only.


There is a workaround for static member functions in C++11, by declaring a variable pointing to the static function:

struct Foo
{
    static void bar()
        { }
};

auto bar = Foo::bar;

Edit: Of course, having a global variable pointing to a static member function is possible in the older C++ standard as well, but it's more messy than using the auto keyword of C++11. In the example above it would be:

void (*bar)() = Foo::bar;
Morton answered 25/7, 2012 at 10:41 Comment(4)
using B = A::B; this will not work. Another point is that function pointers cannot be inlined.Calorifacient
@SergeyK. Works fine for me, with GCC 4.7.1. But you're right about the inlining.Morton
1.cpp:9:7: error: expected nested-name-specifier before 'B' using B = A::B; (gcc.EXE (GCC) 4.8.0)Calorifacient
@SergeyK. Actually, the using keyword syntax is legal in C++11. When compiling with GCC did you use the -std=c++11 or -std=c++0x flags?Morton
E
11

You can typedef

typedef A::B B;
Ecumenicism answered 25/7, 2012 at 10:9 Comment(1)
You could also create f() in the global namespace that calls A::f().Tullis

© 2022 - 2024 — McMap. All rights reserved.