2

Basically, there is a class Foo defined in namespace np:

//Foo.h
namespace np {

    class Foo {
        public:
          static void static_member();
         ...
        }
...
}

I wanted to reference the static member in other sources, say src.cc

//src.cc
#include "Foo.h"

using np::Foo::static_member;
...
static_member()
...

after launching compiler, it complained:

 error: using declaration cannot refer to class member

However, it worked when I changed the line to np::Foo::static_member(). So, what are proper ways to omit the interminable scope prefixes?

Finley
  • 795
  • 1
  • 8
  • 26
  • There is no way unless `Foo` is a namespace, not a `class` (or `struct`) type. The call of the function would also need to be in another function. `np::Foo::static_member()` can be called unqualified in a member function of `np::Foo` – Peter Oct 25 '19 at 07:29

3 Answers3

4

So, what are proper ways to omit the interminable scope prefixes?

There is no way. Outside of class scope, using declarations can refer to nested types in classes, but not to data members, see here.

The shortest you can get is either

using namespace np;
Foo::static_member();

or go with a pointer-to-member, which is shorter but also slightly more confusing:

auto static_member = &np::Foo::static_member;
static_member();
lubgr
  • 37,368
  • 3
  • 66
  • 117
  • Hi, I tried `decltype(np::Foo::static_member)* static_member`(which I think is the same as your second workaround), compilation was successful but program crashed at the call of `static_member()`; I am working with Android NDK, and backtrace did not tell anything about this crash : ( – Finley Oct 25 '19 at 07:40
  • If you go with the `decltype` version you must make sure the pointer-to-member is initialized. The crash you're seeing is probably that you're trying to call a function through a pointer that doesn't point to some valid location in memory. – lubgr Oct 25 '19 at 07:48
2

I'm not sure what your use case is, but I'd go one of two ways (or maybe three?):

1) if it applies try to move this static method into a namespace - since it's static this may work for you (in cases where you need to pass this thing as some sort of templated class, then this approach will not work). See other people's opinion on this:

Namespace + functions versus static methods on a class https://softwareengineering.stackexchange.com/questions/134540/are-utility-classes-with-nothing-but-static-members-an-anti-pattern-in-c

namespace np
{
  void static_non_member();
} // namespace np

// .. in .cpp, should be fine to do this
{
  using namespace np;
  static_non_member();
}

2) using declarations work well with classes so you could at least reduce the amount of writing you have to do:

// assume same hpp
// cpp
#include "Foo.h"

using Foo = np::Foo;

Foo::static_member();

3) bonus round: store a pointer to that function

#include <type_traits>

using FunctionPtrT = std::add_pointer<void()>::type;
FunctionPtrT static_ptr = &Foo::static_member;

// Foo::static_member();
static_ptr(); // name this whatever you wish
ben10
  • 221
  • 1
  • 8
0

You don't have to add using np::Foo::static_member;

You can use any static function if you included Foo.h and if the function is public

For Example:

// Foo.h
namespace np
{
  Class Foo
  {
    public:
      static void PrintHello();
  }
}

// Foo.cpp
#include "Foo.h"
#include <iostream>

void np::Foo::PrintHello()
{
  printf("Hello World!\n");
}

// main.cpp
#include "Foo.h"
int Main()
{
  np::Foo::PrintHello();
}
Lawlets
  • 69
  • 3