Определите эту переменную доступность - PullRequest
1 голос
/ 07 марта 2019

В настоящее время я адаптирую проект Windows C ++, чтобы он работал на Linux.Я определил несколько макросов для печати отформатированных строк в файл журнала.Они похожи на printf, поэтому я могу написать это:

WARN("%d::%s<", 42, "baz");

Довольно просто напечатать что-то вроде:

[thread_id] [WARN] [/ path / to / main.cpp: 15] [Пт 03/01/2019 10: 38: 54.408] [this_value] 42 :: baz <</p>

this_value - это значение это или NULL, если это не определено (статическая функция, внешняя функция "C").

Мой текущий код:

#if defined(_WIN32) && !defined(__INTELLISENSE__)
    #define SET_ZIS __if_exists (this) { zis = this; }
#else
    #define SET_ZIS
#endif

#define _LOG(...) \
    do \
    { \
        void *zis = NULL; \
        SET_ZIS \
        GetLoggerInstance()->logMessage(__VA_ARGS__); \
    } while(0)

#define LOG(...) _LOG(level, __FILE__, __LINE__, __func__, zis, __VA_ARGS__)
#define WARN(...) LOG(ILogger_level::LEVEL_WARN, __VA_ARGS__)

Существует ли стандартный способ определения наличия этого ?Может быть, используя std::is_* или трюк SFINAE?

Я использую функции "C" с внешним интерфейсом для конструирования объектов ("this" не имеет смысла) и вызова членов в экземплярах объектов ("this" имеет смысл).«Конструкторы» экспортируются в общий объект и динамически используются проектом C ++.Делая это таким образом, мне не нужно управлять искаженными именами.

extern "C" int CreateMyClass(std::shared_ptr<MyClass> *newClass);
int CreateMyClass(std::shared_ptr<MyClass> *newClass)
{
  RELAY("(%p)", newClass);
  *newClass = std::make_shared<MyClass>(42, "baz");
  return 0;
}

MyClass::MyClass(int a, char *b)
{
  RELAY("(%d,%s)", a, b);
}

РЕДАКТИРОВАТЬ: Вот простой тестовый пример:

#include <memory> /* For std::shared_ptr */
#define RELAY(...) printf("[%p][%s]\n", this, __func__)

class MyClass
{
public:
  MyClass(int a, const char *b);
  static void test();
};

extern "C" int CreateMyClass(std::shared_ptr<MyClass> *newClass);
int CreateMyClass(std::shared_ptr<MyClass> *newClass)
{
  RELAY("(%p)", newClass);
  *newClass = std::make_shared<MyClass>(42, "baz");
  return 0;
}

MyClass::MyClass(int a, const char *b)
{
  RELAY("(%d,%s)", a, b);
}

void MyClass::test()
{
  RELAY("()");
  printf("some work");
}

int main(int argc, char **argv)
{
  std::shared_ptr<MyClass> newClass;

  int ret = CreateMyClass(&newClass);
  MyClass::test();
  return ret;
}

g ++ даетследующие ошибки:

test.c: In function ‘int CreateMyClass(std::shared_ptr<MyClass>*)’:
test.c:2:41: error: invalid use of ‘this’ in non-member function
 #define RELAY(...) printf("[%p][%s]\n", this, __func__)
                                         ^
test.c:14:3: note: in expansion of macro ‘RELAY’
   RELAY("(%p)", newClass);
   ^~~~~
test.c: In static member function ‘static void MyClass::test()’:
test.c:2:41: error: ‘this’ is unavailable for static member functions
 #define RELAY(...) printf("[%p][%s]\n", this, __func__)
                                         ^
test.c:26:3: note: in expansion of macro ‘RELAY’
   RELAY("()");
   ^~~~~

CreateMyClass не является статическим («функция, не являющаяся членом»), поэтому она недоступна.То же самое для статической функции.

1 Ответ

0 голосов
/ 08 марта 2019

Ссылка this существует и всегда существует внутри нестатических функций-членов класса / структуры c ++.Это указатель на адрес памяти экземпляра класса, над которым работает функция.Что касается ведения журналов, я не уверен, как бы вы использовали это, кроме как копаться в дампе памяти, и я не уверен на 100%, что адрес экземпляра даже пригодится для этого.

...