I am looking for way to get some trace log from compiler's logic when it is trying to deduce template argument types, whenever it successes or not. So for example, given then code:
#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';
}
I'd love to receive something like:
foo(10)
candidate: decltype(auto) foo(T&& t) -> decltype(t * t): seems valid
candidate: decltype(auto) foo(T&& t) -> decltype(t.size()): wrong one
Compilers are pretty good at it already, for example with providing the ambiguous calls. E.g. if I called foo(std::string("qwe"));
I'd get:
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())
^~~
And, if this explicit feedback is not possible, maybe there is a way to get view of "semi-compiled" code, with all template deduction already done?
Does any of compilers have such feature? gcc, clang, mvsc?
This example is quite easy and obvious, but I do experiment with ranges::v3
library and struggle to understand why one specific case does work and why the other does not.
(Technically, iterator_range<Handmade InputIterator>
piped with view::take(3)
returns void
instead of some fancy range
, but is not matter of this question. I want to trace deduction on almost same line, but with iterator_range<ContiguousIterator>
and see the difference.
The compiler tries to deduce a template argument by comparing the type of the corresponding template parameter with the type of the argument used in the function call.
Template argument deduction (C++ only) Template argument deduction (C++ only) When you call a template function, you may omit any template argument that the compiler can determine or deduceby the usage and context of that template function call.
The two types that the compiler compares (the template parameter and the argument used in the function call) must be of a certain structure in order for template argument deduction to work. The following lists these type structures:
Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template, except that a) if the return type is a reference type then P is the referred type;
Templight is a clang-based tool for tracing the progress of template instantiations. It has an interface similar to the gdb debugger, so you can focus in on a certain instantiation that's causing errors or not behaving as expected. Or you can have it output a "profile" of the template instantiations, which would give an overview of all of them.
There's also a related tool Templar which is apparently a graphical interface to Templight's debugger mode, though I haven't tried it myself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With