我正在尋找允許記錄函式輸入引數的功能。例如:
void func(std::string& input_name, const int n){
// print current function's inputs' type, name, and value
}
呼叫該函式后,以下內容將被列印或讀取為字串,
input1:
type: std::string,
name: input_name,
value: "something",
input2:
type: int,
name: n,
value: 12,
有沒有人對這樣的目標有建議
- - - - - - 編輯
如果無法列印型別或名稱,我也可以。我對接近于此的解決方案很靈活,例如我們是否可以獲得輸入引數串列等。
uj5u.com熱心網友回復:
列印變數的型別和值相當簡單。但是變數名在運行時不存在,因此獲取變數名作為字串而不對其進行硬編碼的唯一方法是在編譯時使用宏。宏具有將令牌字串化的功能。
嘗試這樣的事情(抱歉,這是憑記憶,我目前無法使用編譯器,我將在今天晚些時候更新):
#include <iomanip>
#include <typeinfo>
#include <type_traits>
template <typename T>
std::string getTypeName()
{
// TODO: to get a more human-readable output, use
// if-constexpr, or template specialization, or one
// of the solutions from https://stackoverflow.com/q/281818/65863...
return typeid(T).name();
}
template<typename T>
std::string stringify(const T& param)
{
std::ostringstream oss;
if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, char*> || std::is_same_v<T, const char*>)
oss << std::quoted(param);
else
oss << param;
return oss.str();
}
template <typename T>
void doLog(int num, std::string_view name, const T& value)
{
std::cout << "input" << num << ":" << std::endl
<< "\ttype: " << getTypeName<T>() << "," << std::endl
<< "\tname: " << #param << "," << std::endl
<< "\tvalue: " << stringify(param) << "," << std::endl;
}
#define LOG(num, param) doLog(num, #param, param)
void func(std::string& input_name, const int n){
LOG(1, input_name)
LOG(2, n)
}
uj5u.com熱心網友回復:
這是使用模板而不是宏的開始:(確實添加了 typeid.name 可以輸出錯誤名稱的概念)
#include <iostream>
#include <string>
#include <sstream>
namespace details
{
//-------------------------------------------------------------------------
// formatters for parameters to functions
//
template<typename type_t>
std::string format(const type_t& value)
{
std::ostringstream os;
os << typeid(type_t).name() << ":";
os << value;
return os.str();
}
// output boolean as text
std::string format(const bool& value)
{
return value ? std::string("bool:true") : std::string("bool:false");
}
// add quotes to string
std::string format(const char* value)
{
std::ostringstream os;
os << "const char*:\"";
os << value;
os << "\"";
return os.str();
}
// recursively log all parameters
template<typename arg_t, typename... args_t>
inline void log_parameters(bool comma, const arg_t& arg, args_t... args)
{
if (comma) std::cout << ", ";
std::cout << format(arg);
if constexpr (sizeof...(args_t) > 0)
{
// true is print separating comma at next call
log_parameters(true, std::forward<args_t>(args)...);
}
}
//-------------------------------------------------------------------------
template<typename... args_t>
inline void log(const char* function, args_t... args)
{
std::cout << "function call to : " << function << "(";
// if there are any arguments to log do so
if constexpr (sizeof...(args_t) > 0)
{
// false == do not print a comma on first call
log_parameters(false, std::forward<args_t>(args)...);
}
std::cout << ");\n";
}
}
void my_function(const bool x, const int y, const char* str)
{
details::log(__FUNCTION__, x, y, str);
}
int main()
{
my_function(1, 42, "Hello world!");
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/331755.html
下一篇:如何找到“弱”記憶體泄漏
