【问题标题】:Is there any way to trace any compiler's template argument deduction?有没有办法跟踪任何编译器的模板参数推导?
【发布时间】:2018-02-16 13:03:01
【问题描述】:

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

#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 库,并且很难理解为什么一个特定案例有效而另一个案例无效。 (从技术上讲,iterator_range&lt;Handmade InputIterator&gt;view::take(3) 管道返回void 而不是一些花哨的range,但这与这个问题无关。我想在几乎同一行上追踪扣除,但使用iterator_range&lt;ContiguousIterator&gt; 并查看差异.

【问题讨论】:

  • 我担心这种功能会产生大量消息。
  • 您想知道所有推导出来的,而不仅仅是那些与错误有关的吗?
  • @liliscent 是的,因为我的问题是没有错误。操作会编译,但返回类型是void,所以我不能使用它们的结果。
  • @Caninonos 我也是,但我可以将我的问题归结为一行。一行返回 void 而不是我预期的类型。这就是为什么我想跟踪几乎相同的行,但使用返回正确类型并查看差异的类型(在哪个模板推导上,我的类型不适合给定的内部概念)

标签: c++ c++14 c++17


【解决方案1】:

Templight 是一个基于 clang 的工具,用于跟踪模板实例化的进度。它具有类似于 gdb 调试器的界面,因此您可以专注于导致错误或行为不符合预期的某个实例化。或者,您可以让它输出模板实例化的“配置文件”,这将提供所有这些实例化的概览。

还有一个相关的工具Templar,显然是Templight调试器模式的图形界面,虽然我自己没试过。

【讨论】:

  • 很好,谢谢 :) 我已经 +1 你了,我会在几天内接受它,但现在我会暂时保持开放状态,希望得到更多答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2021-05-09
相关资源
最近更新 更多