【问题标题】:Detect this variable availability检测此变量可用性
【发布时间】:2019-03-07 19:46:12
【问题描述】:

我目前正在调整一个 Windows C++ 项目以使其在 Linux 上运行。 我定义了几个宏来将格式化的行打印到日志文件中。 它们类似于 printf,所以我可以这样写:

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

打印以下内容非常容易:

[thread_id][WARN][/path/to/main.cpp:15][2019 年 3 月 1 日星期五 10:38:54.408][this_value] 42::baz

this_valuethis 的值,如果 this 未定义(静态函数,extern “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__)

是否有检测 this 是否存在的标准方法? 也许使用std::is_* 或 SFINAE 技巧?

我使用外部的“C”函数来构造对象(“t​​his”是无意义的)并调用实例化对象的成员(“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 不是静态的(“非成员函数”),所以这是不可用的。静态函数也是如此。

【问题讨论】:

  • 您是在询问 C++ 关键字 this,还是一些非特定变量?
  • 这是一个保留关键字,所以是的,我说的是 C++ this
  • 我在确切名称上留空(现在正在搜索它)但是如果编译单元正在由 C 编译器编译(gcc ) 或 C++ 编译器 (g++)
  • gcc.gnu.org/onlinedocs/cpp/… 列出了__cplusplus,我相信这就是你想要的。
  • 你不明白,我的“C”函数在.cpp 文件中。不过谢谢你的提示。

标签: c++ c-preprocessor


【解决方案1】:

this 引用仅存在且始终存在于 c++ 类/结构的非静态成员函数中。它是一个指向函数正在操作的类实例的内存地址的指针。就日志记录而言,除了挖掘内存转储之外,我不确定您将如何使用它,而且我也不能 100% 确定实例地址是否有用。

【讨论】:

  • 好的。那么有没有办法检测是否是这种情况?
  • 你做事的方式,不,你只需要两个不同版本的LOG
  • 详细说明:宏由预处理器处理,是盲查找和替换操作。预处理器并不真正理解你想要做什么,所以你必须告诉它,我建议只在存在this 的地方使用不同的宏,或者重新考虑打印内存地址的好处你的类实例到日志中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 2013-05-11
  • 1970-01-01
  • 2012-02-29
  • 1970-01-01
  • 2016-08-16
  • 2022-07-11
相关资源
最近更新 更多