我想知道如何编写一个函数来检测参数类型,值和函数名称以及另一个函数的返回值。
例如。我有一个功能:
double average(string datapath, double *data, int numofinput)
{
// some code here
}
我想要另一个函数,例如detector(),它可以插入到要检测的函数中,比如
double average(string datapath, double *data, int numofinput)
{
// some code here
detector();
}
并且探测器将返回:
name: average
returned value: 2.43
pathname: string='C:/Users/Nick/Data/'
data: pointer=0x0065
numofinput: int=17
这样的事情。任何建议都非常感谢。谢谢。 尼克
答案 0 :(得分:2)
一般来说,这是不可能做到的:
detector
需要在实际返回任何内容之前显示返回值,这与心灵阅读相同average
函数可能根本不是函数,因为编译器可以内联它。但是,对于特定情况,您可以获得此信息 - 假设您有可用的调试符号,通常不会这样。
答案 1 :(得分:1)
这是一个(未经测试的)想法:
#define DETECTOR(name, ...) detector_wrapper(name, #name, ##__VA_ARGS__)
template <typename R, typename ...Args, typename ...Brgs>
R detector_wrapper(R(&f)(Args...), char const * name, Brgs &&... brgs)
{
auto && result = f(std::forward<Brgs>(brgs)...);
std::cout << "Function name: " << name << std::endl
<< "Return type: " << demangle(R) << std::endl
<< "Return value: " << result << std::endl;
return result;
}
用法:
double d = DETECTOR(average, path, data, n);
通过更多工作,您还可以打印参数及其值的类型,但不其名称(显然,因为名称不是声明的一部分,只是定义的一部分)
答案 2 :(得分:0)
好的,这是另一种方法,包括打印参数名称和类型。由于两个原因,它不是很优雅:
所以这里是:
#include <iostream>
#define DETECTOR_0ARG_FUNC(RETTYPE, NAME) \
RETTYPE NAME() \
{ \
std::cout << "Function Name: " #NAME << std::endl; \
std::cout << "Returns: " #RETTYPE << std::endl; \
std::cout << "No Parameters" << std::endl;
#define DETECTOR_1ARG_FUNC(RETTYPE, NAME, PARAM1TYPE, PARAM1NAME) \
RETTYPE NAME(PARAM1TYPE PARAM1NAME) \
{ \
std::cout << "Function Name: " #NAME << std::endl; \
std::cout << "Returns: " #RETTYPE << std::endl; \
std::cout << "Pameter 1 (" #PARAM1TYPE " " #PARAM1NAME "): " << PARAM1NAME << std::endl;
#define DETECTOR_RETURN(RETTYPE, VALUE) \
RETTYPE __retval = (VALUE); \
std::cout << "Returning: " << __retval << std::endl << std::endl; \
return __retval;
#define DETECTOR_END_FUNC \
}
DETECTOR_0ARG_FUNC(int, GetFiveFactorial)
int result = 1;
for(int i=5; i>0; i--)
{
result = result * i;
}
DETECTOR_RETURN(int, result)
DETECTOR_END_FUNC
DETECTOR_1ARG_FUNC(int, GetFactorial, int, initVal)
int result = 1;
for(int i=initVal; i > 0; i--)
{
result = result * i;
}
DETECTOR_RETURN(int, result);
DETECTOR_END_FUNC
int main(int argc, char **argv)
{
GetFiveFactorial();
GetFactorial(7);
return 0;
}
输出:
Function Name: GetFiveFactorial
Returns: int
No Parameters
Returning: 120
Function Name: GetFactorial
Returns: int
Pameter 1 (int initVal): 7
Returning: 5040
我有点不建议您这样做。但从理论的角度来看,这种方式是可能的。