Использование директивных классов статических функций? - PullRequest
3 голосов
/ 21 мая 2011

Я использую API, который имеет много функций в классе с именем TCODConsole в качестве статических функций. Теперь я думал, что это было в пространстве имен, поэтому я написал: using namespace TCODConsole;. Затем я обнаружил, что TCODConsole не пространство имен, а класс.

Есть ли способ импортировать эти функции аналогично тому, как вы бы использовали using namespace?

Ответы [ 4 ]

3 голосов
/ 21 мая 2011

Нет, нет быстрого способа вызова myStaticFun() вместо MyClass::myStaticFun(). Вы не можете сделать это с классом. Это класс, а не пространство имен. Но вы можете написать что-то вроде обертки. То есть вы будете добавлять функции с тем же именем и вызывать статические методы из этих функций. Примерно так:

class MyClass {
    static void fun();
};

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

// call it
fun();

Не очень хороший способ. Лично я думаю, что лучше придерживаться класса, а не делать это.

2 голосов
/ 22 мая 2011

Хотя я могу неправильно понять вопрос, если цель состоит в сокращении квалификации, соответствует ли цель typedef следующим образом?

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

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

В качестве альтернативы, если может быть создан экземпляр класса TCODConsole, поскольку static функция-член может вызываться в той же форме, что и нестатическая функция-член, следующий код может соответствовать цели:

int main() {
  TCODConsole t;
  t.f();
  t.g();
}
2 голосов
/ 21 мая 2011

Я не могу придумать чистый способ сделать это, но я могу подумать о каком-то уродливом хаке, который будет работать, пока код, использующий его, является частью класса (и если TCODConsole действительно содержит только статические функции-члены).Допустим, вы bar(), функция-член класса Foo, и вы хотите вызвать функцию baz(), которая является статическим членом TCODConsole, без полной ее квалификации.То, что вы можете сделать, это получить Foo из TCODConsole в частном порядке:

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

};

Да, это ужасно.: (

Если вы хотите использовать Boost.PP (макрос-библиотека препроцессора Boost - вам не нужно компилировать или включать что-либо еще из Boost, чтобы использовать его), вы, вероятно, можете сделать его менее уродливым, но довольнонемного более запутанный макрос, который «импортирует» эти функции для вас, оборачивая их встроенными функциями в другое пространство имен (которое вы затем можете импортировать по своему желанию). При этом вам все равно потребуется явно указать имя каждой функции, которую вы хотите«импортировать», поэтому ваш код (без макроса) будет выглядеть примерно так:

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

, и тогда вы сможете написать using namespace TCODStatic; в любом месте.

0 голосов
/ 21 мая 2011

Краткий ответ: не без использования макросов.В языке C ++ нет механизма, позволяющего сделать что-то вроде этого:

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

// ...

using A;
foo();

Вы можете использовать макрос для построения этих выражений для вас:

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

FOO();

Однако я бы не одобрил этопотому что это может стать кошмаром обслуживания, если вы широко используете такие макросы.Вы получите код, подобный следующему:

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

... где ни одна из этих вещей не определена как первоклассные имена где-либо в программе.Вы потеряли все проверки типов, код использует «секретный язык», который известен только вам, и становится трудно отлаживать, расширять и исправлять.

РЕДАКТИРОВАТЬ:

Вы можете написатьвид моста.Как это:

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

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

using namespace Foo;

gizmo();
...