Observing Compiler Deduced Types¶
Scott Meyers lecture on Type Deduction and Why You Care (at around minute 43) explains a technique to force compilers to display the types it deduces when a function template is instantiated or when an auto variable is defined. Here is the code
template<typename T> TD; // Declaration for TD. TD == "Type Displayer"
template<typename T> void f(T& param) // A template w/types of interest
{
TD<T> tType; // cause T to be shown
TD<decltype(param)> paramType; // ditto for param's type
}
that forces two compile errors that will display both the deduced type for T
and param
. Examples:
int x = 27; // x is an int
f(x); // main.cpp line 67
Using g++ version 7.2.0, the output is:
main.cpp: In instantiation of ‘void f(T&) [with T = int]’:
main.cpp:67:6: required from here
main.cpp:53:9: error: ‘TD<int> tType’ has incomplete type
TD<T> tType; // cause T to be shown
^~~~~
main.cpp:54:24: error: ‘TD<int&> paramType’ has incomplete type
TD<decltype(param)> paramType; // ditto for param's type
^~~~~~~~~
int& rx = x; // rx is a reference to an int
f(rx); // main.cpp line 70
Using g++ version 7.2.0, the output is:
main.cpp: In instantiation of ‘void f(T&) [with T = int]’:
main.cpp:70:6: required from here
main.cpp:60:9: error: ‘TD<int> tType’ has incomplete type
TD<T> tType; // cause T to be shown
^~~~~
main.cpp:61:24: error: ‘TD<int&> paramType’ has incomplete type
TD<decltype(param)> paramType; // ditto for param's type
^~~~~~~~~
const int& crx = x; // crx is a reference to a const int
f(crx); // main.cpp line 74
Using g++ version 7.2.0, the output is:
main.cpp: In instantiation of ‘void f(T&) [with T = const int]’:
main.cpp:74:8: required from here
main.cpp:60:9: error: ‘TD<const int> tType’ has incomplete type
TD<T> tType; // cause T to be shown
^~~~~
main.cpp:61:24: error: ‘TD<const int&> paramType’ has incomplete type
TD<decltype(param)> paramType; // ditto for param's type
^~~~~~~~~
Now if f
is changed to take a const &
, and we re-run the same examples, we get:
template<typename T> void f(const T& param) // template w/types of interest
{
TD<T> tType; // cause T to be shown
TD<decltype(param)> paramType; // ditto for param's type
}
int x = 27;
f(rx); // line 67
the output is:
main.cpp: In instantiation of ‘void f(const T&) [with T = int]’:
main.cpp:67:6: required from here
main.cpp:60:9: error: ‘TD<int> tType’ has incomplete type
TD<T> tType; // cause T to be shown
^~~~~
main.cpp:61:24: error: ‘TD<const int&> paramType’ has incomplete type
TD<decltype(param)> paramType; // ditto for param's type
^~~~~~~~~
int& rx = x; // rx is a reference to an int
f(rx); // line 70
the output is:
main.cpp: In instantiation of ‘void f(const T&) [with T = int]’:
main.cpp:70:7: required from here
main.cpp:60:9: error: ‘TD<int> tType’ has incomplete type
TD<T> tType; // cause T to be shown
^~~~~
main.cpp:61:24: error: ‘TD<const int&> paramType’ has incomplete type
TD<decltype(param)> paramType; // ditto for param's type
^~~~~~~~~
const int& crx = x; // crx is a reference to a const int.
f(crx); // line 74
the output is:
main.cpp: In instantiation of ‘void f(const T&) [with T = int]’:
main.cpp:74:8: required from here
main.cpp:60:9: error: ‘TD<int> tType’ has incomplete type
TD<T> tType; // cause T to be shown
^~~~~
main.cpp:61:24: error: ‘TD<const int&> paramType’ has incomplete type
TD<decltype(param)> paramType; // ditto for param's type
^~~~~~~~~