【问题标题】:can compiler tell me which overloaded or template function it chose?编译器可以告诉我它选择了哪个重载或模板函数吗?
【发布时间】:2012-11-01 17:17:47
【问题描述】:

特别是在 linux 上使用 g++,有没有办法确定为特定语句选择了哪个重载或模板函数?

更具体地说,我并不认为我一定知道所有可能的选择,它们可能位于来自各种库的头文件中。即使我这样做了,我也不认为我可以修改相关代码。

【问题讨论】:

  • stackoverflow.com/questions/1496497/… 可能有用——例如,查看中间编译器步骤。如果您只想这样做一次,您可以查看生成的目标文件,并可能在您想要理解的调用周围粘贴一个“标记”函数调用。目标文件将指示它调用的函数的符号名称,可以将其还原为您调用的函数签名(应该是唯一的)。
  • 我经常说,我们需要的是一个编译时调试器,这样您就可以在评估模板实例化时单步执行它们,查看模板参数等,看看什么是真正的继续。
  • 当你说 see 时,你到底是什么意思? Clang 因为 C++ 生成完整的 AST 而臭名昭著,但是您需要围绕其库编写程序才能“看到”。
  • 你想解决什么问题?
  • @PeteBecker:你知道有没有人按照这些思路做任何工作?那将是一个不可思议的工具。

标签: c++ templates template-specialization overload-resolution


【解决方案1】:

我不知道有什么方法可以直接做到这一点。

最简单的解决方案是在调用处设置断点,然后单步执行调用的任何函数;然后你的调试器可以告诉你你在哪个函数中。

Eclipse CDT 这样的 IDE 可以自己进行重载和模板解析(如果一切正常的话),所以右键单击函数调用并转到函数声明将带您到适当的函数。

通过故意创建一个模棱两可的函数调用,如this answer 中所述,您可以获得所有可用重载和模板的列表,并且可能可以确定从那里调用了哪个。

正如 Matthieu M. 所说,Clang 可以dump its AST。这需要一些解释,但它可以帮助您确定正在调用的函数。

【讨论】:

  • 谢谢。如果 Eclipse 真的能做到这一点,我会印象深刻,那将是一个不错的解决方案。
  • @c-urchin - 让 Eclipse 正确识别各种源文件和头文件可能很棘手,特别复杂的 C++ 代码很少会混淆它,但一旦它工作起来就非常好。
  • @c-urchin - MS VS 也可以做到。将鼠标光标移动到函数名称上,可以看到调用重载函数的名称和重载函数的个数。我认为任何现代 IDE 都必须这样做。
【解决方案2】:

部分回答。

您可以使用非标准宏在运行时打印函数名称 (Macro / keyword which can be used to print out method name?

对于 GNU C++:

#include <iostream>
using namespace std;
template <typename T>
void f(const T & t)
{
   cout << __PRETTY_FUNCTION__ << endl;
}
void f(const string &)
{
   cout << __PRETTY_FUNCTION__ << endl;
}
void f(int)
{
   cout << __PRETTY_FUNCTION__ << endl;
}
int main()
{
    f(1.0);
    f(1);
    f(string("sss"));
    string a;
    f(a);
}

此代码的输出 (http://ideone.com/PI39qK):

void f(int)
void f(int)
void f(const std::string&)
void f(T&) [with T = std::string]

【讨论】:

  • 谢谢,但正如我所说,我不能假设我可以修改源代码,或者我什至知道哪些代码可能是候选代码,因为它可能来自任何#include'd 文件(在任何级别)
猜你喜欢
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多