Intellisense not working with templates VS2012 ultimate c++ - c++

Intellisense is working very badly with my VS...
When I'm coding in C++ it works 100% fine, until I start using templates, then it just stops working completely, stops detecting errors and don't auto-complete in all cases.
I'm inclined to believe it has to do with something I have done with my code that broke it.
So I started by creating a class with a struct in it:
template<typename T>
class List<T>
{
private:
struct Node
{
T value;
Node* next;
Node* previous;
};
Node* First;
Node* Last;
...
};
later, I declare some additional functions:
template<typename T>
inline T List::First()
{
return First;
}
so far so good, intellisense is working 100% fine, but if I try to do first-> it won't work, VS won't tell give me any options (ctrl + space doesn't work).
also, if I type some nonsense it won't tell me it's wrong:
sdkjgisjdga->vsrsiib = 123jgi;
I don't really know what to do in order to fix this.
Thank you for your time and efforts.
PS: I already tried to reset the configurations.
EDIT: Forgot to say that if i don't use templates in my .h file then intellisense works correctly.

Templates need to be instantiated before you can definitively say what they contain. For example, your First-> snippet points to a List<T>::Node, and that is obviously dependent on the exact T.
Sure, Intellisense in this simple case could unambiguously list the members by just substituting T==int for a moment. But consider what's worse: Intellisense not knowing the members (like now) or Intellisense mis-guessing in the hard cases where you need it most?

I am a bit late with this answer, and maybe the OP is not working on this code anymore, but I think this may still help someone who is searching templates and IntelliSense.
One thing you can try -- if you want to be able to see your typos and errors as you type, but if you want your code to be template-able -- is using an #if-#else-#endif:
#if MY_USE_TEMPLATES
template <typename T>
#else
typedef [**your-test-type-here**] T;
#endif
class List {
... your code here ...
}
In Visual Studio 2015 this seems to work. You can define MY_USE_TEMPLATES to be 0 (using a #define), develop your code with IntelliSense and auto-complete, etc. (so you make less mistakes), and then change the MY_USE_TEMPLATES to 1 when you are ready to test or compile with actual template code.
While you have MY_USE_TEMPLATES turned on, code that references your List will result in error (i.e., code like 'List myList'), and you can resolve that with an extra dummy 'template' inside the #else statement. However, the good thing about leaving the #else clause without an extra 'template' is: the error you get when referencing your List may serve you as a reminder to turn on MY_USE_TEMPLATES before testing the code, reducing the probability of a bug. (Experience suggests that it is easy to forget when handling a lot of things and large projects ...)
Do be careful about using multiple such type definitions, however: the 'typedef ... T' can only be safely used once for that name "T"; while you can use 'typedef ... TYPE1' for one class and 'typedef ... TYPE2' for another, you cannot safely use the same type name for different types unless you put the different type names into separate namespaces. (I tried this in Visual Studio 2015.)

Related

Switching from MSVC14 to MSVC16 leads to "compiler is out of heap space (C1060)" error

I'm trying to switch from the Visual Studio 14 2015 compiler to Visual Studio 16 2019 to compile my project (also tried Visual Studio 15 2017, but that resulted in the same issues). I'm using irrequietus/typestring, which worked perfectly fine with the old compiler but leads to errors now.
Here's a class that's supposed to be used with a typestring:
// my_custom_class.h
template<typename T>
class MyCustomClass
{
public:
static bool compareTheTypestring(const std::string& other) const {
return std::strcmp(data(), other.c_str()) == 0;
}
}
This is how I use the class:
// use_it.cpp
#include "typestring.hh"
#include "my_custom_class.h"
typedef MyCustomClass<typestring_is("Foo")> FooCompare;
Which spits out the following error in typestring.hh:
compiler is out of heap space (C1060).
And more errors in use_it.cpp:
irqus::typeek: no matching overloaded function found (C2672)
Failed to specialize function template 'unknown-type irqus::typeek(irqus::typestring<C...>)'
cannot deduce template arguments for MyCustomClass
The repository contains a similar issue, but the maintainer doesn't seem to reply. I tried to find alternative typestring implementations, but couldn't. Can anyone help me to resolve this, please?
This issue has already been reported in january, with 0 responses since then. It seems the library is no longer being updated... maybe look for an alternative solution
You should really add the details of what you are trying to do into your question. Has to read through the external library before I understood what it is you are trying to achieve. My best suggestion would be: look for an alternative. There are other ways for compile-time strings. Template arguments are probably not the best answer.
If you really want to use the template argument strings, you'll have to fix it yourself. The library was probably relying on undefined behavior. So it's broken now.
I was trying it, but it's not very straight forward. You'll probably need to use the charizing operator in macro's to split the string, and then put the chars into a tuple-type...
template<char c>
class CharType {
public:
static constexpr char Char = c;
};
using FooString = std::tuple<CharType<'F'>, CharType<'o'>, CharType<'o'>>;
Or something like that.

I'm constantly getting error C2797 when using a struct in a class and it's only happening in a specific project

I'm working on a project in Visual Studio that includes a "portable" menu GUI for anyone who wants it in their own work. Since I keep getting the C2797 compiler error, I can't use structs at all since nothing has helped and I use classes a lot.
Basically, I can't use structs, even though it's the most important part of my project.
Menu.h:
struct menuItem
{
const char *name;
bool value;
};
Test.h:
#include "Menu.h"
class Test
{
public:
menuItem dummy = { "Useless option", false }; // <--This is where I get C2797
};
Again, this won't compile, but if I use this exact code in a simple C++ console app, it works flawlessly on all compiler versions.
If you need more details, when I use structs outside of classes, I get C4430 intertwined with C2440 and C2065. (And adding cstdint doesn't help that) If I try using the exact same struct in the closest situation possible in a different project, it compiles with all compiler versions just fine.
For the people who might think that it's because of the VS 2013 compiler (Which I'm using), I've already switched between newer and older versions between all of my projects and it made no difference.
For the other people who didn't see my details in the comments: Pastebin of errors in the console
The fix, as the documentation for the error states, is to explicitly construct the struct on the RHS of the assignment rather than trying to get the compiler to deduce the type of the brace-initializer (which it is unable to do correctly). Like this:
class Test
{
public:
menuItem dummy = menuItem{ "Useless option", false }; // Note the extra menuItem
};
I believe it's because you're not allowed to initialize variables inside the public: unless they are static. Maybe if you try
public:
static const menuItem={"Useless option", false }; // might work

Default template parameters?

I am currently trying to make an old project in C++ work with more recent tools: the project has been developped on Windows XP with VC71 and I am now trying to make it run on Windows 7 with VC100.
I didn't get any "big" problem yet but however I am having a last compilation issue which led me to some code - pretty obscure to me -.
Here is a sample of the macro (simplified) I am having trouble with:
#define IMPORT_STD_PAIR( _keyClass_ ,_objectClass_) \
extern template struct std::pair< _keyClass_,_objectClass_ >; \
...
The error is:
C2955: 'std::allocator' : use of class template requires template argument list.
I don't really get what it is supposed to do (the 2nd line), specify default parameters to a templated class ?
Thank you for your help.
Edit:
#Mark B: Thank you for you answer. You made me realize what was going on: Nothing.
In fact, it is my fault cause I am not familiar at all with developping on Windows. The code was originally:
#define IMPORT_STD_MAP( _import_directive_, _keyClass_ ,_objectClass_) \
extern template struct _import_directive_ std::pair<_keyClass_,_objectClass_>;
I neglected _import_directive_ cause it was almost "empty" in every case but one. So when it is empty, it simply creates an instance with no name which is not really relevant; but when this macro takes the value __declspec ( dllimport ) it makes much more sense :)
Thanks for helping me realizing that, I thought it was something more exotic, and thank you for the debugging advice which has been useful.
It looks like ListRemake is a templated class and you're trying to instantiate an instance as
ListRemake myList;
You need to specify the template arguments for ListRemake
ListRemake<int, long> myList;
It looks like it's attempting to instantiate a specific instantiation of std::pair. Without more context I can't see why this would be attempted, but you might try just making the macro define to nothing and see if the code compiles, links, and appears to work. They may have changed template compiling in 10.0.

(C++ and gcc) error: expected constructor, destructor, or type conversion before 'inline'

I have a header file with some inline template methods. I added a class declaration to it (just a couple of static methods...it's more of a namespace than a class), and I started getting this compilation error, in a file that uses that new class.
There are several other files that include the same .h file that still compile without complaint.
Googling for the error gives me a bunch of links to mailing lists about bugs on projects that have a similar error message (the only difference seeming to be what the constructor, destructor, or type conversion is supposed to precede).
I'm about ready to start stripping everything else away until I have a bare-bones minimal sample so I can ask the question intelligently, but I figured I'd take a stab at asking it the stupid way first:
Can anyone give me a basic clue about what this error message actually means so I might be able to begin to track it down/google it?
Just for the sake of completeness, the first example of where I'm seeing this looks more or less like
namespace Utilities
{
template <typename T> GLfloat inline NormalizeHorizontally(T x)
{
GLfloat scaledUp = x*2.0;
GLfloat result = scaledUp / Global::Geometry::ExpectedResolutionX;
return result;
}
}
It means that you put the "inline" keyword in the wrong place. It needs to go before the method's return type, e.g.
template <typename T> inline GLfloat NormalizeHorizontally(T x)
Simple as that.
The reason that you got this message on one compilation unit and not others may be because it is a templated function that was not being instantiated from those other compilation units.
Generally, if you get an "expected blah blah before foobar" error, this is a parsing error and it often indicates a simple syntax mistake such as a missing semicolon, missing brace, or misordered keywords. The problem is usually somewhere around the portion mentioned, but could actually be a while back, so sometimes you have to hunt for it.

VS2008 internal compiler error

I'm consistently running into an internal compiler error while attempting to switch from MSVC6 to MSVC 2008. After much work commenting out different parts of the program, I've traced the error to two lines of code in two different CPP files. Both of these CPP files compile successfully, yet somehow have an effect on whether or not the error manifests in other files.
Both of those lines involve instantianting several complex, nested templates. They also appear to be the only places in the app that use an abstract class as one of the template parameters. That said, I'm far from certain that the issue involves either abstract classes or templates, it's just the most obvious thing I've noticed. I can't even be sure that these lines are significant at all. Here's what they look like, though:
m_phDSAttributes = new SObjDict<RWCString, SIDataSource>(&RWCString::hash);
So we've got SObjDict, a templatized dictionary class, SIDataSource, an abstract interface, and the parameter is a pointer to a static member function of RWCString.
I've been playing around with the code some, and I can occasionally get the error to move from one CPP file to another (for instance, I changed a bunch of template declarations from using class to typename), but I can't find any rhyme or reason to it.
I'm at a loss as to how to debug this issue further. The exact error output by the compiler (with the name of my source file changed) is below. There is no mention of it anywhere on the internet. I'm pretty desperate for any advice on how to proceed. I don't expect someone to say "oh, you just need to do XYZ", but a pointer on how to debug this sort of issue would be greatly appreciated.
1>d:\Dev\webapi.cpp : fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 5905)
The trick seems to be disabling precompiled headers. I have no idea why that solves the problem, and it's very unfortunate since my build time for the affected project has gone from less than 30 secs to nearly 5 minutes, but at least I can progress forward.
It's a reasonable bet to assume that p2symtab.c is (part of) the symbol table code. This would immediately explain how the upgrade caused it; this code has been rewritten. (Remember the 255 character length warnings of VC6?)
In this case, there is no new entry in the symbol table, so it's likely a lookup in the symbol table failing spectactularly. It would be interesting to see if the context in which th name lookup happens affects the result. For instance, what happens if you change the code to
typedef SObjDict<RWCString, SIDataSource> SObjDict_RWCString_SIDataSource;
m_phDSAttributes = new SObjDict_RWCString_SIDataSource(&RWCString::hash);
This will force another symbol table entry to be created, for SObjDict_RWCString_SIDataSource. This entry is sort of a symbolic link to the template instantiation. The new name can (and must) be looked up on its own.
Start breaking it down into smaller parts. My first guess is the pointer to the static function is going to be the problem. Can you make a dummy non-template class with the same parameter in the constructor? Does it compile if you don't use an abstract class in the template?
Looks like I'm sending you in the wrong direction, the following compiles fine in 2008:
class thing {
public:
static void hash( short sht ) {
}
void hash( long lng ) {
}
};
class thing2 {
public:
thing2( void (short ) ){}
};
int _tmain(int argc, _TCHAR* argv[])
{
thing2* t = new thing2( &thing::hash );
delete t;
return 0;
}
The principle remains though, remove/replace complex elements until you have code that compiles and you'll know what is causing the problem.
fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c
i also observed the same error when i try to build my vs 2005 code to vs 2008. but it happen till i have not installed Service pack of VS 2008...
have you installed Service pack... i think this will resolved your issue....
This typically happens with template instantiation. Unfortunately it could be caused by many things, but 99% of the time your code is subtly invoking undefined behavior.