Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
 All Forums
 Visual Assist
 Technical Support
 code completion and templates

You must be registered to post a reply.
Click here to register.

Screensize:
UserName:
Password:
Format: BoldItalicizeUnderlineStrikethrough Align leftCenterAlign right Insert horizontal ruleUpload and insert imageInsert hyperlinkInsert email addressInsert codeInsert quoted textInsert listInsert Emoji
   
Message:

Forum code is on.
Html is off.

 
Check to subscribe to this topic.
   

T O P I C    R E V I E W
bta Posted - Sep 05 2018 : 06:09:02 AM
Hi,

as we are modernizing our C++ codebase we are more and more making use of templates to reduce boilerplate code.
Unfortunately it seems this causes some features like code completion (or find references) to stop working.
Just wanted to report this, so you guys might make improvements.

In the following code sample you can see the introduction of a templated checked_deref function.
The idea is that in development builds the extra assert is done and in production builds, this check is not happening.
The thing is that when using the templated variant, no code completion popup is shown when typing the . after the function call, while this is happening when using the non templated variant of the function.

Also, when doing a Find References on getValue() from class X only shows the call following the non-templated nonTemplatedCheckedDeref() function and not that one of the templated checked_deref.


#include <assert.h>

template <typename T>
inline T &checked_deref(T *ptr)
   {
   assert(ptr);
   return *ptr;
   }

X& nonTemplatedCheckedDeref(X* x)
   {
   assert(x);
   return *x;
   }

class X
   {
   public:
      int getValue() const { return 242; }
   };

int main()
   {
   X x;
   X* px = &x;

   int value = 0;
   value = nonTemplatedCheckedDeref(px).getValue();   // code completion kicks in
   value = checked_deref(px).getValue(); // no code completion

   return 0;
   }


As said, as we are modernizing our code base quite a lot of templated functions are being introduced, so better support by VAX for this would be very helpfull!

Thanks!

Bart

Environment:
VA_X.dll file version 10.9.2283.0 built 2018.07.12
DevEnv.exe version 15.6.27428.2027 Professional
4   L A T E S T    R E P L I E S    (Newest First)
feline Posted - Sep 06 2018 : 09:58:42 AM
Interesting, thank you for the link and the example. I am much more used to template classes than template functions, as you can probably tell I was simply unaware that it was possible to have the compiler working out the type for a template function, since I don't recall ever seeing it done before, but it does make perfect sense when you see it.

Not understanding this is definitely a bug / limitation in our parser, which we are aware of, but unfortunately I don't currently have an estimate for when this will be fixed.
bta Posted - Sep 06 2018 : 03:31:03 AM
The fact that we do not explicitly specify the template parameters for templated functions is common practice.
The compiler deduces the template arguments.
Consider the std::find algorithm (see https://en.cppreference.com/w/cpp/algorithm/find) and the following example mentioned on that page:

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
 
int main()
{
    int n1 = 3;
    int n2 = 5;
 
    std::vector<int> v{0, 1, 2, 3, 4};
 
    auto result1 = std::find(std::begin(v), std::end(v), n1);
    auto result2 = std::find(std::begin(v), std::end(v), n2);
 
    if (result1 != std::end(v)) {
        std::cout << "v contains: " << n1 << '\n';
    } else {
        std::cout << "v does not contain: " << n1 << '\n';
    }
 
    if (result2 != std::end(v)) {
        std::cout << "v contains: " << n2 << '\n';
    } else {
        std::cout << "v does not contain: " << n2 << '\n';
    }
}


The std::find function is a templated function since it can accept different types of iterators and contained types, but having to specify the template arguments explicitly would be very cumbersome (especially these iterator types are very verbose).
The compiler just deduces the types from the actual parameters that are supplied.
Also, if you explicitly typed the template paramaters and if the type of the container you do the find on would change later on, you would have to modify the places where you call the find as well...

So really hoping that you guys can fix the issue!

Thanks,

Bart
feline Posted - Sep 05 2018 : 11:39:46 AM
I thought something seemed wrong here, and now I have figured out what felt wrong. You are calling the template function without specifying the type the template acts on, it is being worked out from the parameter. It compiles, which is interesting, since I am not used to seeing templates used without stating the type explicitly.

If you keep the template function the same, and change the function call to become:

value = checked_deref<X>(px).getValue();

then VA should work correctly for you. This change fixes the problem here for me.
feline Posted - Sep 05 2018 : 07:28:20 AM
Thank you for the clear example. I am a little surprised we are having this problem here, but clearly we are:

case=66730

if it helps, a more complex version of this template code works correctly with VA. Instead of the template function I have a template class, so that something is actually created with the type you are checking:

template<typename T>
class classCheckDefer
{
public:
	T& checked_deref(T *ptr)
	{
		assert(ptr);
		return *ptr;
	}
};


and then use it like this:

classCheckDefer<X> checkX;
checkX.checked_deref(px).getValue();


but this is more cumbersome, removing some of the benefits of moving to template code.

© 2021 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000