繁体   English   中英

如何在预处理阶段获取c ++函数调用者名称

[英]How to get c++ function caller name at preprocessing stage

我必须使用库中的宏PERF_INSTRUMENT PERF_INSTRUMENT期望用户提供c样式字符串作为函数名称来打印此仪器点的位置。

但是,我不想每次使用PERF_INSTRUMENT写入函数名称,而是想用__func__调用它,以便函数名自动包含在perf日志中。

但是当我使用__func__它实际上返回operator()因为__func__嵌入在lambda函数中。

他们可以通过哪种方式将main()函数名称传递给PERF_INSTRUMENT宏。

#include <cstdio>
#include <cassert> 
#include <type_traits> 

using namespace std;

namespace /* anonymous */
{
    template< typename T >
    struct Is_Const_Char_Array
      : std::is_same< std::remove_reference_t< T >,
                      char const[ std::extent< std::remove_reference_t< T > >::value ] >
    {};

    template< typename T >
    struct Is_C_String_Literal
      : Is_Const_Char_Array< T >
    {};
}

#define PERF_INSTRUMENT(name)  auto instObj = [] { static_assert( Is_C_String_Literal< decltype( name ) >::value, "input argument must be a c-string literal" ); /* Some other Logic*/ printf(name);return 1; }()


// <------------------ MY CODE -------------------> //

int main(){
    PERF_INSTRUMENT("main"); // <-- this works fine
    PERF_INSTRUMENT(__func__); // <-- this prints operator()
    // PERF_INSTRUMENT(__builtin_FUNCTION());
}

请注意,我只能更改MY CODE行下面的代码

他们可以通过哪种方式将主函数名称传递给PERF_INSTRUMENT宏。

您可以将“ name ”作为参数传递给lambda本身。

有点像

#define PERF_INSTRUMENT(name) \
    auto instObj = [](char const * str) \ // <-- receive an argument
       { static_assert( Is_C_String_Literal< decltype( name ) >::value, \
                       "input argument must be a c-string literal" );\
         /* Some other Logic*/ \
         printf(str); \  // <-- print the argument received, not directly name
         return 1;\
       }(name)
//.......^^^^   pass name as argument

Bonus Off主题建议:检测是一个对象是一个C字符串文字,我提出了另一种方法

template <typename T>
constexpr std::false_type islHelper (T, long);

template <typename T, std::size_t N>
constexpr std::true_type islHelper (T const(&)[N], int);

template <typename T>
using isStringLiteral = decltype(islHelper(std::declval<T>(), 0));

static_assert()成为

static_assert( isStringLiteral<decltype(name)>::value,
               "input argument must be a c-string literal" );

由于断言从根本上是有缺陷的 - 它接受任何const char数组 - 将宏包装在另一个宏中应该有效。
像这样的东西:

#define PERF_FUNCTION do { \
    const char name[] = __func__; \
    PERF_INSTRUMENT(name); \
} while(0)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM