Я должен использовать макрос PERF_INSTRUMENT
из библиотеки. PERF_INSTRUMENT
ожидает, что пользователь предоставил строку в стиле c в качестве имени функции, чтобы напечатать местоположение этой точки инструмента.
Но я не хочу писать имя функции каждый раз, когда использую PERF_INSTRUMENT
вместо этого я хочу назвать это с __func__
так что имя функции автоматически включается в журнал перфорации.
Но когда я использую __func__
это на самом деле возвращается operator()
поскольку __func__
встроен в лямбда-функцию.
Есть ли какой-нибудь способ, которым я могу пройти 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());
}
Обратите внимание, что я могу изменить только код ниже строки МОЙ КОД
Есть ли какой-нибудь способ, которым я могу передать имя главной функции в макрос PERF_INSTRUMENT.
Вы можете пройтиname
«в качестве аргумента самой лямбда.
Что-то как
#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
Бонус от темы предложение: обнаружить объект является литералом 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)