当我使用__FUNCTION__
宏/变量打印出调试信息时,使用Microsoft C++编译器和gcc时输出的内容似乎有所不同.例如,使用以下简单代码:
class Foo
{
public:
void Bar(int a, int b, int c)
{
printf ("__FUNCTION__ = %s\n", __FUNCTION__);
}
};
int main (void)
{
Foo MyFoo;
MyFoo.Bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到了使用Microsoft Visual C++编译器
__FUNCTION__ = Foo::Bar
Run Code Online (Sandbox Code Playgroud)
而在使用gcc编译时(在本例中是在Mac上),我得到了
__FUNCTION__ = Bar
Run Code Online (Sandbox Code Playgroud)
第二个例子并不理想,因为我经常有几个类,比方说Init()
和Uninit()
方法,并且在调试输出跟踪中,几乎不可能知道哪个类被调用,因为类名将丢失.现在,我知道你可以使用__PRETTY_FUNCTION__
代替它__FUNCTION__
来获得类似的东西
__PRETTY_FUNCTION__ = void Foo::Bar(int, int, int)
Run Code Online (Sandbox Code Playgroud)
这很好,但它对于我需要的东西有点过于冗长,并且对于具有大量参数的函数来说有点长.
所以我的问题是(最后),有没有办法让输出看起来像简单地Foo::Bar
使用gcc,如上例所示?
我使用 g++ 4.8.1 并使用这两个宏进行调试。但是,__func__
宏只给了我函数名,如果您在不同的类中有许多具有相同名称的函数,这可能会产生误导。该__PRETTY_FUNCTION__
宏生成整个函数签名 - 带有返回类型、类名和所有参数,这些参数可能很长。
我想要一些东西 - 一个宏,它只会给我类名和函数名。有什么方法可以实现吗?
有没有办法在编译时隐式引用类的名称?
具体来说,如果我想在的范围内声明template class A
using 的实例,是否可以避免在声明该实例的语法中明确引用“ B” ?class B
class B
class A
为了更好地说明一个例子:
// main.cpp
#include <iostream>
using namespace std;
template <typename T>
class A
{
public:
typedef void (T::*TFunc)();
A( T& t ) : t_( t ) {}
void callFunc( TFunc tFunc ) { (t_.*tFunc)(); }
private:
T& t_;
};
class LongClassName
{
public:
LongClassName() : a_( *this ) {}
void pubFunc()
{
a_.callFunc( &LongClassName::privFunc ); // Can I avoid explicitly using "LongClassName" here?
}
private: …
Run Code Online (Sandbox Code Playgroud) 有没有一种方法可以struct
在 said 声明的顶层一般获取 a 的类型struct
,而不引用其struct
本身的实际名称?
例如:
#include <type_traits>
struct example {
using attempt1 = example; // <- obvious, but not what I want
using attempt2 = decltype(*this); // <- error
using attempt3 = std::remove_pointer<decltype(this)>::type; // <- error
};
Run Code Online (Sandbox Code Playgroud)
或者:
#include <type_traits>
struct { // anonymous
//using attempt1 = ...;
using attempt2 = decltype(*this);
using attempt3 = std::remove_pointer<decltype(this)>::type;
} x;
Run Code Online (Sandbox Code Playgroud)
这些程序当然无法在 GCC 9.x 和 10.x 上的 C++17 和 C++2a 模式下编译(“在顶层无效使用‘this’”),但我想做类似的事情attempt2
或者attempt3 …
这个想法来自/sf/answers/1104286361/
我在 string_view 末尾添加了一个 '\0',这样我们就可以将 data() 用于 printf、spdlog 等。
我使用这个宏来打印带有类名的函数名。
但是,我发现编译器不够智能,无法内联字符串,而是需要先进行内存复制才能堆栈:
https://godbolt.org/z/bqob37G3z
请参阅 main 函数中 CALL 和 CALLFUNC 的区别。
是否可以告诉编译器将字符串放在某个 RO 部分中,例如 const char *?
template<std::size_t N>
consteval const std::array<char, N> __get_function_name(const char * arr)
{
std::array<char, N> data {};
std::string_view prettyFunction(arr);
size_t bracket = prettyFunction.rfind("(");
size_t space = prettyFunction.rfind(" ", bracket) + 1;
size_t i;
for (i = 0; i < bracket - space; i += 1) {
data[i] = arr[space + i];
}
data[i] = '\0';
return …
Run Code Online (Sandbox Code Playgroud)