-1

I get this strange behaviour from VS2017 working won C++ project: Intellisence is missing - i just type plain text with no warnings, And it still compiles:

enter image description here

No errors are shown in the whole file. However, when i try the same everywhere outside this function's scope, everything works as expected:

enter image description here

The problem occurs in my generic function implementation:

#pragma region Public API
template <typename Key, typename Value>
void BinarySearchTree<Key, Value> ::Put(Key key, Value val)
{
    Node node = root_;
    if(node.key == null)
        sadadasd
        affsa
        dasds
        dasdsad
        asdsad
}

#pragma endregion

Class defined like this:

template <typename Key, typename Value>
class BinarySearchTree {};

Again, it is dead silent - no red/yellow at all. Compiled code even runs. It is as if that part is comented out.

Tried reloading VS, did not help

TheSmokingGnu
  • 302
  • 2
  • 6
  • 15
  • Are you actually instantiating this template anywhere in your code? – Ron Nov 02 '17 at 16:07
  • @Ron i can put this into main, e.g : ``BinarySearchTree bst;`` with no errors – TheSmokingGnu Nov 02 '17 at 16:09
  • Errors in templated code are delayed until the template gets expanded. Surely that never happened. – Hans Passant Nov 02 '17 at 16:09
  • 2
    I don't know why everyone's bringing instantiation into this. Templates are still checked for syntax errors before instantiation, and checked further for the parts that don't depend on the template parameters. This is an MSVC bug that will probably be fixed when they fully support two-phase lookup. – chris Nov 02 '17 at 16:12
  • 1
    If anyone is wondering, the mass downvoting is me. I downvoted anyone who implied that this behavior is correct (which is everyone so far). – Benjamin Lindley Nov 02 '17 at 16:15
  • @VTT so to debug syntax errors i need to build solution with a call to every method that is generic? Is that just impossible to check in real-time by compiler? – TheSmokingGnu Nov 02 '17 at 16:16
  • @TheSmokingGnu, Until MSVC supports it, compile with more than one compiler. VS has built-in Clang support, and Clang properly gives errors here. Being able to run your code through more than one compiler also opens the door to catching bugs that one compiler can discover, but the other can't. – chris Nov 02 '17 at 16:20

5 Answers5

5

This is a known issue with Visual C++ that has existed for a long time. It does not implement two-phase lookup. It basically just completely skips over templates until they are instantiated. Apparently, they finally fixed it (at least partially).

https://blogs.msdn.microsoft.com/vcblog/2017/09/11/two-phase-name-lookup-support-comes-to-msvc/

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • It looks like the partial support is already out. I was able to get an error with http://webcompiler.cloudapp.net/ and `/permissive-`. – chris Nov 02 '17 at 16:45
3

As per class template reference:

A class template by itself is not a type, or an object, or any other entity. No code is generated from a source file that contains only template definitions. In order for any code to appear, a template must be instantiated...

Update: This appears to be a Visual C++ specific bug. Other compilers are likely to issue an error.
Trivial example for GCC

More info on the subject in this SO post:
What exactly is "broken" with Microsoft Visual C++'s two-phase template instantiation?

Ron
  • 14,674
  • 4
  • 34
  • 47
1

Class template instantiation A class template by itself is not a type, or an object, or any other entity. No code is generated from a source file that contains only template definitions. In order for any code to appear, a template must be instantiated: the template arguments must be provided so that the compiler can generate an actual class (or function, from a function template).

Serhiy
  • 1,332
  • 1
  • 16
  • 24
-1

Until you use your template with arguments, it will not be instanciated, so it will not exists, and thus there will be no errors.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
Arkady
  • 2,084
  • 3
  • 27
  • 48
  • Yes, errors are shown upon build, with a member instantiated.... but are you telling me that I have to build solution to detect syntax errors in template implementations, and that i get NO intellisence at all while writing them? – TheSmokingGnu Nov 02 '17 at 16:12
  • In general it is useless to check correctness of template until you don't know template parameters. Because template may allow you to call something like `T.dance();`, and you can't check if it is correct before you know if `T` has function `dance()` – Arkady Nov 02 '17 at 16:18
  • @Arkady, As evident by the OP's concerns, it's not useless to check correctness earlier. There are a great number of errors you can find while writing the template instead of while testing it (or worse, you didn't write a test and there's a problem with it after it's been released). The standard calls out which parts need to be dealt with later. – chris Nov 02 '17 at 16:23
  • @chris, look at this as at task. You need to create very clever checking system, for such hard cases like `T.sdfsd` before you know what is `T` and does it have member `sdfsd`, and noone need it if not using. But as only someone is using it, you get full check with all use case variants for free. So, no reason to solve this problem. Nice to have it, but definitely it is not something important, I think. That is why it lives so long in VS – Arkady Nov 02 '17 at 16:28
  • 1
    @Arkady, That's why `T.sdfsd` is delayed. You delay things that depend on template parameters and check things that don't. But this isn't an ideal. This is how C++ is specified. The compiler **must** do this, and MSVC doesn't (yet). – chris Nov 02 '17 at 16:30
  • @chris, I agree with you, and nice to know that there exists even demand in C++ specification for such case, I didn't before you mentioned it. But I were explaining why it was not presented. – Arkady Nov 02 '17 at 17:08
  • @TheSmokingGnu remember that Intellisense is *not* the compiler. It's merely a tool that tries to give you helpful hints - and in a short time, so it's quite constrained in what it can do. It's also not based on the same code base as the compiler, so it may (correctly and incorrectly) complain about different things. – Jesper Juhl Nov 02 '17 at 17:16
-1

Templates are only compiled into the binary when instantiated. If you don't use the template, the code is thrown away

LordAro
  • 1,269
  • 3
  • 18
  • 35