Reputation: 845
There is a template member function named at
in class cv::Mat
of OpenCV:
//definition of at
template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const{
// ...
}
//my codes
cv::Mat eyePts_left;
// ...
if(std::max(eyePts_left.at<float>(0,0),eyePts_left.at<float>(16,0)) > eyePts_left.at<float>(61,0)){
//do something
}
I want to print the value of the expression:
eyePts_left.at<float>(0,0)
in an lldb debugging session, but it complains:
(lldb) p eyePts_left.at<float>(0, 0)
error: warning: warning: got name from symbols: at
error: <user expression 21>:1:13: no member named 'at' in 'cv::Mat'
eyePts_left.at<float>(0, 0)
~~~~~~~~~~~ ^
error: <user expression 21>:1:21: expected '(' for function-style cast or type construction
eyePts_left.at<float>(0, 0)
~~~~~^
So, what is the proper way to check the value of this template-related expression?
Upvotes: 2
Views: 630
Reputation: 27148
The current debug information for template functions, and templated entities in general is awkward because it only describes instantiations, and not templates as abstract entities, so templated functions just show up in the debug info just as functions with angle brackets somewhere in the names. That makes it tricky to go from the debug info to a compiler representation that lldb can feed into its copy of clang so that clang can parse them correctly in expressions. As you have found, that doesn't work at present.
If you really need to do this however, you can work around the problem with a little creative casting, for instance:
Find the function address, e.g.
(lldb) image lookup -n Mat::at<float>
1 match found in /tmp/a.out:
Address: a.out[0x0000000100003f30] (a.out.__TEXT.__text + 64)
Summary: a.out`float const& Mat::at<float>(int, int) at template_fun.cpp:4
Cast the call to that address by hand:
(lldb) expr ((float &(*) (Mat *, int, int))0x0000000100003f30)(&my_mat, 10, 20)
Called with 10 20
(float) $0 = 30
This isn't your real function, just a toy I made so don't pay attention to the actual result.
Note, if you end up doing this often and don't 100% love C function casting syntax, you can make a typedef for it, either in the code or in lldb like:
(lldb) expr typedef float &(*$Mat_at_type) (Mat *, int, int)
That simplifies the call:
(lldb) expr (($Mat_at_type)0x0000000100003f30)(&my_mat, 10, 20)
Called with 10 20
(float) $1 = 30
And then if you end up doing this a whole lot, you could even do:
(lldb) command alias call_at expr -- (($Mat_at_type)0x0000000100003f30)
(lldb) call_at (&my_mat, 10, 20)
Upvotes: 2