本文介绍了从类T和成员函数指针void(T :: * pmf)()获取函数名(__func__)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以编写一些 f()模板函数,它接受一个类型 T 函数签名 void(T :: * pmf)()作为(模板和/或函数)参数并返回 const char * 指向成员函数的 __ func __ 变量(或转义函数名称)?

Is it possible to write some f() template function that takes a type T and a pointer to member function of signature void(T::*pmf)() as (template and/or function) arguments and returns a const char* that points to the member function's __func__ variable (or to the mangled function name)?

strong> EDIT :我被要求解释我的用例。我试图写一个单元测试库(我知道有一个库)。 我的目标是不要使用任何宏

EDIT: I am asked to explain my use-case. I am trying to write a unit-test library (I know there is a Boost Test library for this purpose). And my aim is not to use any macros at all:

struct my_test_case : public unit_test::test {
    void some_test()
    {
        assert_test(false, "test failed.");
    }
};

我的测试套件将调用 my_test_case :: some_test c $ c>如果其断言失败,我想要它日志:

My test suite runner will call my_test_case::some_test() and if its assertion fails, I want it log:

ASSERTION FAILED (&my_test_case::some_test()): test failed.

我可以使用< typeinfo> 获取类的名称,但是指针到成员函数只是一个偏移量,它不能为用户提供关于调用的测试函数的线索。

I can use <typeinfo> to get the name of the class but the pointer-to-member-function is just an offset, which gives no clue to the user about the test function being called.

推荐答案

这似乎是你想要实现的,是在 assert_test()中获取调用函数的名称。使用gcc,您可以使用
。这里是一个天真的例子:

It seems like what you are trying to achieve, is to get the name of the calling function in assert_test(). With gcc you can use backtace to do that. Here is a naive example:

#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

输出:

ASSERTION FAILED my_test_case::some_test(): test failed.

注意:这是一个gcc(linux,...)解决方案,到其他平台!

Note: This is a gcc (linux, ...) solution, which might be difficult to port to other platforms!

这篇关于从类T和成员函数指针void(T :: * pmf)()获取函数名(__func__)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 01:16