This problem comes up very often when I'm developing software or resolving bugs: I need to know where the data that's being passed into a function or method is coming from to know how it's being set.
For example,
template<typename AType, typename BType>
ReturnTypeT foo(AType &a, BType &b);
Or the following for a method of a class that has a trait
TraitT::FooType::ReturnT bar(TraitT::FooType::ArgT &arg);
In CLion, there's a Find Usages
feature that works well for pretty "standard" C++ code, and I can quickly jump up the call stack. It doesn't work for templated code. I've found two ways to deal with this: using grep
or using the debugger, putting a breakpoint inside the function/method and looking at the call stack.
However, sometimes running the application doesn't trigger the method and I want to know why. What state caused this method to never be called? It's simple if the grep
results aren't that big, and I can logically deduct who's calling it. It's more complicated when I'm grepping for a pretty generic method name that's called in plenty of places, such as variadic CRTP. How do you efficiently find who was supposed to call that method but didn't in that case?
Finally, there's a last case of dealing with templates that comes up very often. I want to know what data or methods I can call on the template type. With non-templated code, I can just use the Find Usages
and it brings me to the class definition. I can then inspect the attributes or interface to see if it already has what I need. I can use the template type as a template parameter in an incomplete type variable declaration and the compiler will tell me what it is. Simple enough if the template type doesn't use variadic CRTP. If it does, then I have to inspect the class definitions of each base, and so on. Is there a simple way to just display all the methods that can be called on the template type and all the attributes it contains?
Also, please share any other tricks for developing software with highly templated code.