我必须使用库中的宏PERF_INSTRUMENT
。 PERF_INSTRUMENT
期望用户提供的c样式字符串作为函数名称来打印该仪器点的位置。
但是,我不想每次使用PERF_INSTRUMENT
时都写函数名,而是想用__func__
来调用它,以便函数名自动包含在性能日志中。
但是当我使用__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());
}
请注意,我只能更改“我的代码”行下方的代码
答案 0 :(得分:5)
通过它们的任何方式,我都可以将主函数名称传递给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 Topic提案:检测是否一个对象是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" );
答案 1 :(得分:0)
由于断言从根本上来说是有缺陷的-它接受任何const
char数组-将宏包装在另一个宏中应该可以。
像这样:
#define PERF_FUNCTION do { \
const char name[] = __func__; \
PERF_INSTRUMENT(name); \
} while(0)