有没有办法跟踪任何编译器的模板参数推导?

Is there any way to trace any compiler's template argument deduction?

本文关键字:参数 跟踪 任何 编译器 有没有      更新时间:2023-10-16

我正在寻找方法来从编译器的逻辑中获取一些跟踪日志时,无论是否成功,它都试图推断模板参数类型。因此,例如,给定代码:

#include <iostream>
#include <vector>
#include <type_traits>
template<typename T>
decltype(auto) foo(T&& t) -> decltype(t + t)
{
    return t + t;
}
template<typename T>
decltype(auto) foo(T&& t) -> decltype(t.size()) 
{
    return t.size();
}
int main()
{
    std::cout << foo(10) << 'n'
              << foo(std::vector<int>{1,2,3}) << 'n';
}

我很想收到类似的东西:

foo(10)
candidate: decltype(auto) foo(T&& t) -> decltype(t * t): seems valid
candidate: decltype(auto) foo(T&& t) -> decltype(t.size()): wrong one

编译器已经很擅长,例如提供模棱两可的电话。例如。如果我打电话给foo(std::string("qwe"));,我会得到:

main.cpp: In function 'int main()':
main.cpp:23:31: error: call of overloaded 'foo(std::__cxx11::basic_string<char>)' is ambiguous
         foo(std::string("qwe"));
                               ^
main.cpp:7:20: note: candidate: decltype ((t + t)) foo(T&&) [with T = std::__cxx11::basic_string<char>; decltype ((t + t)) = std::__cxx11::basic_string<char>]
     decltype(auto) foo(T&& t) -> decltype(t + t)
                    ^~~
main.cpp:13:20: note: candidate: decltype (t.size()) foo(T&&) [with T = std::__cxx11::basic_string<char>; decltype (t.size()) = long unsigned int]
     decltype(auto) foo(T&& t) -> decltype(t.size())
                    ^~~

,如果无法进行此明确的反馈,也许有一种方法可以查看"半编译"代码,并且所有模板扣除已经完成?

任何编译器都有这样的功能吗?GCC,Clang,MVSC?

背景:

这个示例非常容易且显而易见,但是我确实对ranges::v3库进行了实验,并难以理解为什么一种特定情况确实可以起作用,而另一个情况不行。(从技术上讲,用view::take(3)管道的iterator_range<Handmade InputIterator>返回void,而不是一些花哨的range,但对这个问题并不重要。我想在几乎同一行上跟踪扣除,但是使用iterator_range<ContiguousIterator>,请参阅差异。

templight是一种基于叮当的工具,用于追踪模板实例的进度。它具有与GDB调试器相似的接口,因此您可以专注于某些导致错误或不按预期行为的实例化。或者,您可以使其输出模板实例化的"配置文件",这将概述所有这些。

还有一个相关的工具圣殿骑士,显然是Templight调试模式的图形接口,尽管我没有自己尝试过。