我正在寻找从编译器逻辑中获取一些跟踪日志的方法,当它试图推断模板参数类型时,无论何时成功或不成功。 例如,给出代码:
#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<Handmade InputIterator>
使用view::take(3)
管道返回void
而不是某些花哨的range
,但这个问题无关紧要。我想在几乎相同的线路上追踪扣除,但是与iterator_range<ContiguousIterator>
一起看看差异。