How can I find out what type the compiler deduced when using the auto
keyword?
Example 1: Simpler
auto tickTime = 0.001;
W
@jonathan-oconnor points out that you can use the [[deprecated]] attribute introduced in C++14 to produce a very clean solution:
template<typename T>
[[deprecated]] constexpr void printType(T const&) {}
Unfortunately though, the diagnostic emitted by MSVC doesn't mention the type. (example)
I like to use idea from Effective Modern C++ which uses non-implemented template; the type is output with compiler error:
template<typename T> struct TD;
Now for auto variable var
, after its definition add:
TD<decltype(var)> td;
And watch error message for your compiler, it will contain type of var
.
typeid can be used to get the type of variable most of the time. It is compiler dependent and I've seen it give strange results. g++ has RTTI on by default, not sure on the Windows side.
#include <iostream>
#include <typeinfo>
#include <stdint.h>
#include <chrono>
#include <ctime>
typedef std::ratio<1, 1> sec;
int main()
{
auto tickTime = .001;
std::chrono::duration<double, sec > timePerTick2{0.001};
auto nextTickTime = std::chrono::high_resolution_clock::now() + timePerTick2;
std::cout << typeid(tickTime).name() << std::endl;
std::cout << typeid(nextTickTime).name() << std::endl;
return 0;
}
./a.out | c++filt
double
std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >
As a side note, to effectively print out the value in nextTickTime
you should explicitly convert to a suitable std::chrono::duration and output the result of duration::count.
using std::chrono::duration_cast;
using std::chrono::seconds;
auto baseTime = ...;
std::cout << std::setprecision(12) << duration_cast<seconds>(nextTickTime - baseTime).count()
<< std::endl; // time in seconds
A low tech solution is hover the mouse over nextTickTime
which in some GUIs gives the type else set a .
after nextTickTime
in the cout
and select a reasonable looking value or function.
In general if You know what type You get use auto
if you don't know it don't use it. Which is a bit counter intuitive.
So if you know its a interator just use auto to reduce the incantations, if the result is some unknown type you have to find out what it is before using auto
.
See also Herb, Andrei and Scott discussing auto
The type deduced by the compiler is in the error message:
/usr/include/c++/4.8.2/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>;
_Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<double, std::ratio<1l, 1000000000l> > >]’
^^ <-------- the long type name --------------------------------------------------------------------------------------->
It's a complicated type name but it is there in the error message.