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.
Related
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.)
I can't for the life of me figure out what the compiler wants from me.
Can anyone experienced with compiler messages help me decipher what it wants, please?
I can't even provide code bits because I've no idea whats going on.
I'm using g++-4.7 with -std=c++11
http://pastebin.com/AxYMd6L8
It seems it complains about SimpleMapSquare and something about it being an allocator?
It's nothing like that. SimpleMapSquare is defined as:
#pragma once
namespace BlackDragonEngine
{
struct SimpleMapSquare
{
int TileID;
};
}
I wrote about 400+ lines of templated code yesterday and just tried to include the header for it in my main app and boom this happens...
I don't even know where to start...please help.
EDIT:
A search for "vector<" in my project returns this: http://i.imgur.com/g8L1l.png
I expanded the revelant files (the ones I created yesterday)
The reason I wrote so much code without testing is because I'm converting my engine from C# to C++, so the logical side is already right and I can't test incomplete code.
EDIT 2:
Here are all usages of "SimpleMapSquare" http://i.imgur.com/zedkh.png
EDIT3:
Thanks to Konrad I was able to pinpoint the exact line and find the error... ignore the searches above as I forgot to include *.inl files (where the template code implementation is located)
You are using the following class somewhere:
class std::vector<sf::Vector2<int>, BlackDragonEngine::SimpleMapSquare>
The second type argument of std::vector is the allocator type!
Looks like SimpleMapSquare shold contain definition of types value_type, pointer and reference.
It is like the STL is treating SimpleMapSquare as an iterator, allocator or other traits requiring classes.
Did you pass it as a wrong parameter somewhere ?
I have a function as
AddSprintf(char* , ... )
I want to make compile time error if somebody is calling it without two arguments.
Currently if somebody is calling like
AddSprintf("hello")
it works. But I want to disable calling like this.
Is there any way using g++ I can force passing of argument ?
Overload AddSprintf:
void AddSprintf(const char* , ... ) {}
void AddSprintf(const char*);
Then you get a weird error message when compiling AddSprintf("hello")
But keep in mind that with C++11 you should use variadic templates because they are typesafe.
What about
AddSprintf(char* , char*, ... )
?
You can't, really. The dots stand for "zero or more arguments", and there is no way of knowing if there is any arguments. Except maybe using assembler and do some checking of the stack pointer.
As 0A0D says, it's variadic - by definition, the compiler is going to be fine with it. If you want it to fail at compiler time, you may have to pull tricks - for example, if you're unit testing, have code that makes the function fail with one argument call, so that new programmers will know they can't do that.
That said, why are you trying to do this? There may be a better solution to your problem.
If you want to stick to the same name, then you can use variadic macro:
#define AddSprintf(X,...) AddSprintf(X,__VA_ARGS__)
But be very careful with this solution, as AddSprintf would work first as text replacement in preprocessing stage. Then only it would be a function.
I have some code that PC-Lint is giving me Error 503: Boolean argument to relational on. It is a call to a template function which is defined like this:
template <typename ITypeToUse>
void ShowWindowEx(
HWND hWnd,
int nCmdShow,
ITypeToUse *pControl);
The call itself looks like this:
ShowWindowEx<IActualType>(this->GetWndHandle(), SW_SHOW, m_spControl);
Appearantly, the part ShowWindowEx<IActualType>(...) is interpreted as Identifier1 < Identifier2 > Expression... PC-Lint seems not to be aware that ShowWindowEx is a template function which requires a type in angled brackets and tries its best to interpret it as a boolean expression.
I am aware that I can simply tell lint to ignore this error for this line (though in reality it's about 30 lines), but I'd like to prevent this from happening again. Also, as far as I know, PC-Lint should be capable of handling template function calls, any idea why this is not the case here?
The declaration is inside a class in a header and the call is in another member function of that class, which is declared right before ShowWindowEx is. The implementation of both member functions happens in the .cpp file in the same order, so the call to ShowWindowEx happens before its implementation. Is it possible PC-Lint just ignored the header?
EDIT:
I now changed the function prototype to:
template <typename IPointerToUse>
void ShowWindowEx(
HWND hWnd,
int nCmdShow,
IPointerToUse pControl);
So the template will take care of the type being a pointer. Thanks DeadMG for the suggestion. Question still stands, as I see no reason the above should not have worked, but it works this way as well.
503 normally is a C warning, not C++. Can it be that your C++ file containing the template function call is considered a C file by Lint, maybe by using *.C (capital letter) on a Windows machine? or using a non-standard extension?
I've seen this happen when using Samba to Lint a Unix C++ program on a Windows PC Lint installation.
If this is still an issue, look at the output lines indicating the module names like --- Module: ..., and look at the file type between parentheses. If switched off, you may need to use -vm (default).
If this is the case, I would expect many more warnings around the call, but interpreting the template <...> as two comparison operators would legitimately provoke this warning.
Other than that, the line you presented - without context - does not give any reason why 503 could be applicable here.
Perhaps the reason is that there is already a definition of ShowWindowEx (one that is no template definition) in the Windows headers.
Perhaps you should try to rename your function.
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.