此问题描述了如何使用__PRETTY_FUNCTION__获取函数的全名,包括其返回类型,参数类型,命名空间和模板参数.
考虑以下,美丽的功能:
namespace foo {
namespace {
template<int i>
int (*bar(int (*arg)(int *)))(int *) {
printf("%s\n", __PRETTY_FUNCTION__);
return arg;
}
} // anonymous namespace
} // namespace foo
Run Code Online (Sandbox Code Playgroud)
如果你不明白,该函数接受并返回一个指向int *- > int函数的指针.
用g++(4.9)编译时,它的名字很漂亮,
int (* foo::{anonymous}::bar(int (*)(int*)))(int*) [with int i = 1337]
Run Code Online (Sandbox Code Playgroud)
并且,clang++(3.5),
int (*foo::(anonymous namespace)::bar(int (*)(int *)) [i = 1337])(int *)
Run Code Online (Sandbox Code Playgroud)
这些字符串非常不适合测试函数是否是某个命名空间的一部分.有没有其他方法,或者说,编译器提供的库来解析这些字符串?
为了澄清,我宁愿有类似的东西
foo::{anonymous}::bar <I don't care about anything beyond this point>
Run Code Online (Sandbox Code Playgroud)
更理想的是,我想要一种编译时的方式,比如一个产生某种列表的constexpr函数split(__PRETTY_FUNCTION__)
等等,但我对完全合格的函数名称感到满意.
经过更仔细的观察,我写了这段代码:
template <typename InputIterator, typename T>
InputIterator findClosing( InputIterator first, InputIterator last, T close )
{
if (first == last)
return last;
auto open = *first;
unsigned counter = 1;
while (++first != last)
{
if (*first == close && --counter == 0)
return first;
if (*first == open)
++counter;
}
return last;
}
template <std::size_t N,
std::size_t N2>
std::string f(char const(&str)[N], char const(&name)[N2])
{
using namespace std;
// Argument to isalnum must be unsigned:
auto cond = [] (unsigned char c) {return !isalnum(c) && c != '_';};
auto iter = str;
for (;;++iter)
{
iter = search( iter, end(str),
begin(name), end(name)-1 );
if (iter == end(str))
throw invalid_argument("");
if ((iter == begin(str) || cond(iter[-1]))
&& (iter == end(str) - N2 || (cond(iter[N2-1]) && iter[N2-1] != ':')))
break;
}
auto origin_iter = iter;
while(iter != begin(str))
{
--iter;
for (auto p : {"()", "{}"})
if (*iter == p[1])
iter = findClosing(reverse_iterator<char const*>(iter+1),
reverse_iterator<char const*>(begin(str)),
p[0]).base()-2;
if (cond(*iter) && *iter != ':')
return string(iter+1, origin_iter+N2-1);
}
return string(iter, origin_iter+N2-1);
}
Run Code Online (Sandbox Code Playgroud)
它应该适用于任何函数,假设其中不存在不必要的空格__PRETTY_FUNCTION__并且__func__仅包含非限定函数名称。
| 归档时间: |
|
| 查看次数: |
1794 次 |
| 最近记录: |