是否可以写一些f()
接受类型的模板函数T
和一个指向签名成员函数的指针void(T::*pmf)()
作为(模板和/或函数)参数并返回const char*
指向成员函数的__func__
变量(或损坏的函数名称)?
EDIT:我被要求解释我的用例。我正在尝试编写一个单元测试库(我知道有一个升压测试 http://www.boost.org/doc/libs/1_59_0/libs/test/doc/html/index.html用于此目的的库)。我的目标是根本不使用任何宏:
struct my_test_case : public unit_test::test {
void some_test()
{
assert_test(false, "test failed.");
}
};
我的测试套件运行程序将调用my_test_case::some_test()
如果它的断言失败,我希望它记录:
ASSERTION FAILED (&my_test_case::some_test()): test failed.
我可以用<typeinfo>
获取类的名称,但指向成员函数的指针只是一个偏移量,这无法向用户提供有关正在调用的测试函数的任何线索。
看来您想要实现的目标是获取调用函数的名称assert_test()
。通过 gcc 你可以使用backtace http://www.gnu.org/software/libc/manual/html_node/Backtraces.html要做到这一点。这是一个简单的例子:
#include <iostream>
#include <execinfo.h>
#include <cxxabi.h>
namespace unit_test
{
struct test {};
}
std::string get_my_caller()
{
std::string caller("???");
void *bt[3]; // backtrace
char **bts; // backtrace symbols
size_t size = sizeof(bt)/sizeof(*bt);
int ret = -4;
/* get backtrace symbols */
size = backtrace(bt, size);
bts = backtrace_symbols(bt, size);
if (size >= 3) {
caller = bts[2];
/* demangle function name*/
char *name;
size_t pos = caller.find('(') + 1;
size_t len = caller.find('+') - pos;
name = abi::__cxa_demangle(caller.substr(pos, len).c_str(), NULL, NULL, &ret);
if (ret == 0)
caller = name;
free(name);
}
free(bts);
return caller;
}
void assert_test(bool expression, const std::string& message)
{
if (!expression)
std::cout << "ASSERTION FAILED " << get_my_caller() << ": " << message << std::endl;
}
struct my_test_case : public unit_test::test
{
void some_test()
{
assert_test(false, "test failed.");
}
};
int main()
{
my_test_case tc;
tc.some_test();
return 0;
}
编译为:
g++ -std=c++11 -rdynamic main.cpp -o main
Output:
ASSERTION FAILED my_test_case::some_test(): test failed.
注意:这是一个 gcc (linux, ...) 解决方案,可能很难移植到其他平台!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)