简体   繁体   中英

Access class subtype via object

class Foo{

public:
    struct Bar{};

};

...

Foo foo;

foo.Bar bar; //error

My compiler says invalid use of struct Foo::Bar . Here of course I can name the subclass Foo::Bar if I want but if foo has a very long nested-template type and/or was created with auto then it would be convenient to access subtypes via object like this.

*Edit: To be clear, I want to create an object of type Foo::Bar, without having to write Foo:: .

Following similar previous responses, using the decltype specifier :

class Foo{

public:
    struct Bar{};

};

int main() {
    Foo foo;
    decltype(foo)::Bar bar;
    const Foor foofoo;
    decltype(foofoo)::Bar barbar;
}

Edit: including solution for references or pointers

#include <type_traits>
...

void fref(const Foo &foo) {
   typename std::remove_reference<decltype(foo)>::type::Bar bar;
}

void fpointer(Foo *foo) {
   typename std::remove_reference<decltype(*foo)>::type::Bar bar;
}

[...] but if [F]oo has a very long nested-template type [...]

OK, assuming you have:

class Foo
{
    template <typename T>
    class SomeVeryLongAndInconvenientName;
};

you can define an alias for, either with specific type:

using ShorterName = Foo::SomeVeryLongAndInconvenientName<SomeType>;

or as template:

template <typename T>
using ShorterName = Foo::SomeVeryLongAndInconvenientName<T>;

if foo has a very long nested-template type and/or was created with auto then it would be convenient to access subtypes via object like this.

You can use the following strategy.

  1. Declare a member function that returns the type. There is no need to define it unless it is useful otherwise.

  2. Use decltype to let the compiler derived the type from the member function.


Here's an updated version of your posted code.

class Foo {

   public:
      struct Bar{};

      // Just the declaration is sufficient.
      Bar b() const;

};


int main()
{
   Foo foo;
   decltype(foo.b()) bar;
}

If you have a member of the struct Bar inside the class Foo , you can use decltype :

class Foo{
public:
    struct Bar{};
    Bar f_bar; 

};

Foo foo;
decltype(foo.f_bar) bar;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM