Reputation: 12940
While programming with the auto
keyword it would sometimes be convenient to know the type that is used by the compiler at compile time. It does not matter if the compilation aborts where I need to know the type. Simple example:
std::vector< int > s{1, 2, 3};
for (auto elem : s) {
elem = 5;
}
for (auto elem : s) {
std::cout << elem << std::endl;
}
will print
1
2
3
because elem is of type int
, not int&
. It would be nice to try compile the code and get the type of elem
to catch such mistakes early.
Upvotes: 4
Views: 5457
Reputation: 217448
Classical way is to declare template structure without definition:
template <typename> struct Debug;
and then use it:
template struct Debug<std::string>;
or
for (auto elem : s) {
Debug<decltype(elem)>{};
elem = 5;
}
Message error looks like
error: explicit instantiation of 'struct Debug<std::__cxx11::basic_string<char> >' before definition of template
template struct Debug<std::string>;
^~~~~~~~~~~~~~~~~~
error: invalid use of incomplete type 'struct Debug<int>'
Debug<decltype(e)>{};
BTW, now some IDEs show the type when mouse is over auto
or the variable.
Upvotes: 14
Reputation: 12940
Actually I just found an answer to my own question:
template<typename T>
void show_type_abort_helper()
{
return __PRETTY_FUNCTION__;
}
#define show_type_abort(x) show_type_abort_helper< decltype(x) >()
Usage:
std::vector< int > s{1, 2, 3};
for (auto elem : s) {
show_type_abort(elem);
elem = 5;
}
Produces the following error message with g++
(version 6.1.1):
$ g++ test.cpp
test.cpp: In instantiation of ‘void show_type_abort_helper() [with T = int]’:
^^^
test.cpp:17:9: required from here
test.cpp:7:12: error: return-statement with a value, in function returning 'void' [-fpermissive]
return __PRETTY_FUNCTION__;
Check the output at T = int
to see the compiler uses int
as type. This seems to work with clang as well:
$ clang++-3.8 -std=c++11 test.cpp
test.cpp:7:5: error: void function 'show_type_abort_helper' should not return a value [-Wreturn-type]
return __PRETTY_FUNCTION__;
^ ~~~~~~~~~~~~~~~~~~~
test.cpp:17:9: note: in instantiation of function template specialization 'show_type_abort_helper<int>' requested here
^^^
show_type_abort(elem);
Changing to for (const auto& elem : s)
gives
with T = const int&
^^^^^^^^^^
or
show_type_abort_helper<const int &>
^^^^^^^^^^^
So it seems I can find out the type at compile time and abort. This just came in handy for a very complex type that consisted of several typedefs and template parameters where I just could not see what was going on.
Upvotes: 3