Using-directive class static functions?


Keywords:c++ 


Question: 

I am using an API that has a lot of functions in a class named TCODConsole as static functions. Now I thought that it was in a namespace, so I wrote: using namespace TCODConsole;. Then I found out that TCODConsole ain't a namespace, but a class.

Is there a way to import those functions in a similar way as you would use using namespace?


4 Answers: 

Though I may misunderstand the question, if shortening the qualification is the objective, does typedefing like the following meet the purpose?

struct TCODConsole {
  static void f();
  static void g();
};

int main() {
  typedef TCODConsole T;
  T::f();
  T::g();
}

Alternatively, if the class TCODConsole can be instantiated, since static member function can be called with the same form as non-static member function, the following code might meet the purpose:

int main() {
  TCODConsole t;
  t.f();
  t.g();
}


No, there is no shortcut way to call myStaticFun() instead of MyClass::myStaticFun(). You cannot do that with class. It's a class, not a namespace. But you can write something like a wrapper. That is you will add functions with same name and call the static methods from that functions. Something like this:

class MyClass {
    static void fun();
};

void fun() {
    MyClass::fun();
}

// call it
fun();

Not a very good way. Personally I think it is better to stick with the class instead of doing this.



I can't think of a clean way to do it, but I can think of a kinda ugly hack that will work, as long as the code using it is part of a class (and if TCODConsole really contains only static member functions). Let's say you are bar(), a member function of the class Foo, and you want to call a function baz() which is a static member of TCODConsole without fully-qualifying it. What you can do is to privately derive Foo from TCODConsole:

class Foo : private TCODConsole
{
    void bar()
    {
        baz();
    }

};

Yeah, that's ugly. :(

If you want to use Boost.PP (the Boost Preprocessor macro library - you don't need to compile or include anything else from Boost to use it), you can probably make a less ugly but quite a bit more convoluted macro which will "import" these functions for you, by wrapping them with inline functions inside another namespace (which you can then import at will). It would still require you to explicitly specify the name each of the functions you want to "import", so your code (minus the macro) will look something like this:

namespace TCODStatic
{
    IMPORT_FROM_TCOD(foo)
    IMPORT_FROM_TCOD(bar)
    IMPORT_FROM_TCOD(baz)
    IMPORT_FROM_TCOD(spaz)
}

and then you'll be able to write using namespace TCODStatic; anywhere you want.



Short answer: not without using macros. There is no mechanism in the C++ language proper to do something like this:

class A
{
public:
  static void foo();
};

// ...

using A;
foo();

You could use a macro to build these expressions for you:

#define FOO() (A::foo())

FOO();

I would discourage this however, because it can become a maintennence nightmare is you make extensive use of such macros. You end up with code like this:

FOO();
BAR();
SUPERGIZMO(a, b, c);

...where none of these things are defined as first-class names anywhere in the program. You've lost all type checking, the code uses a "secret language" that only you know, and it becomes difficult to debug, extend and fix.

EDIT:

You could write a kind of bridge. Like this:

class FooBar
{
public: 
  static void gizmo();
};

namespace Foo
{
  void gizmo() { FooBar::gizmo(); };
};

using namespace Foo;

gizmo();