Problem with explicit instantiation
Hi template gurus:
Using MS V2008 I found a problem that I'm unable to surmount. Here is a minimal reconstruction:
// header.h
#pragma once
#include <map>
struct pXXX {
std::string p1_;
std::string p2_;
std::string p3_;
};
std::map <std::string, pXXX> xMAP;
std::map<std::string, pXXX>::iterator itXXX;
#define FNAM(flag) (#flag, oxxx)
#define XXX_2(R,N,A,B)\
template <typename R, typename A, typename B> struct X_2 {\
pXXX oxxx;\
X_2 () {\
oxxx.p1_ = typeid(R).name();\
oxxx.p2_ = typeid(A).name();\
oxxx.p3_ = typeid(B).name();\
itXXX = xMAP.begin();\
xMAP.insert (itXXX, std::pair<std::string, pXXX> FNAM(N));\
}\
};
// main.cpp
#include <iostream>
//#include <conio.h>
//#include <iomanip>
#include <sstream>
#include "cabecera.h"
// XXX_2(int,name,int,int) // L.1
template <typename R, typename A, typename B> struct X_2 { // L.2
pXXX oxxx;
X_2 () {
oxxx.p1_ = typeid(R).name();
oxxx.p2_ = typeid(A).name();
oxxx.p3_ = typeid(B).name();
itXXX = xMAP.begin();
xMAP.insert (itXXX, std::pair <std::string, pXXX>("name", oxxx));
}
}; // */
int main () {
X_2 <int, int, int> x2; // M.L.1
std::cout << "\nPress Enter to exit..." << std::endl;
std::cin.get();
return 0;
}
As is, the program compiles and run Ok, but when commenting the template definition of L.2 and uncommenting the L.1, who suposedly produces the same definition (see header.h), the compiler shown an error in M.L.1: "error C2975: 'X_2' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression".
The question is: ¿Are there some way to do that? Any suggestion would be wellcome.
Thanks in advance.
Re: Problem with explicit instantiation
Please use code tags when posting code. This way, the code becomes formatted, readable and will lack the smileys.
Code:
int main()
{
// stuff
}
That is an example of using code tags.
Secondly, there is nothing Visual C++ specific about your question (it is generic C++ using the C++ standard libraries), therefore it should have been posted in the non-Visual C++ forum.
Third, get rid of the macro, create a real template, and remove all the code that doesn't mean anything to your problem (for example, remove the code that does work and those includes that are not relevant to the problem). Then instantiate with a one line instantiation in main(). This way, the code you posted will be full, complete, and half the size it is now, making it much easier to pinpoint and diagnose your problem.
Fourth:
Code:
#include <map>
struct pXXX {
std::string p1_;
std::string p2_;
std::string p3_;
};
Where is the inclusion of <string> in this header?
Fifth, start with this:
Code:
template <typename R, typename A, typename B>
struct X_2
{
R m_R;
A m_A;
B m_B;
void DoNothing() {}
};
int main ()
{
X_2 <int, int, int> x2;
x2.DoNothing( );
}
I expect to see a template class called X_2 that takes three template arguments. The code above compiles -- change the exact code I have posted and duplicate the error that you're seeing. Note you don't need map, string, or anything other than simple data types and a simple template struct/class.
Last, it gets even more difficult to solve your problem when you have variables and types similar names (XXX, XX,X_2 XX_2, etc.). Make your life easier and give your variables meaningful unique names, meaningful enough so it makes sense, and unique enough so that it doesn't confuse you or us looking at your code.
Regards,
Paul McKenzie
Re: Problem with explicit instantiation
Paul:
Thank a lot for your answer. Although I'm not sure to been fully understood all your advices, I try to follow them, so there is the new code -the error remains-.
I've been posted in this forum because I supposed that the error was specific to MS compiler, although I can not reproduce it in other environment to verify it.
I posted the code who work beside the erroneous one, because is just the fact that two supposedly equivalent codes, one work an the other show an unjustified -as far as I know- error.
I apologize for the inclusion of those smileys in the code, but I don't understand exactly what means "use code tags" in this context and/or how use it -obviously the English is not my native language-.
// header.h
#pragma once
#include <map>
#include <string>
struct PARAMS {
std::string p1_;
std::string p2_;
std::string p3_;
};
std::map <std::string, PARAMS> xMAP;
std::map<std::string, PARAMS>::iterator itMAP;
#define FNAM(flag) (#flag, oparams)
#define PARAMS_2(R,N,A,B)\
template <typename R, typename A, typename B> struct X_2 {\
PARAMS oparams;\
X_2 () {\
oparams.p1_ = typeid(R).name();\
oparams.p2_ = typeid(A).name();\
oparams.p3_ = typeid(B).name();\
itMAP = xMAP.begin();\
xMAP.insert (itMAP, std::pair<std::string, PARAMS> FNAM(N));\
}\
void DoNothing() {}\
};
// main.cpp
#include <iostream>
#include <sstream>
#include "header.h"
PARAMS_2(int,name,int,int)
int main() {
X_2 <int, int, int> x2;
}
Re: Problem with explicit instantiation
Just below the New Thread button there's a announcement Before you post...
If you click on that you end up here http://www.codeguru.com/forum/announcement.php?f=7 and in the section Including Code there's a code tags link.
Re: Problem with explicit instantiation
Quote:
Originally Posted by
oldnewbie
Paul:
Thank a lot for your answer. Although I'm not sure to been fully understood all your advices, I try to follow them, so there is the new code -the error remains-.
You're still not using code tags.
Second, either get rid of the #define macro and replace with regular template code, or turn on the preprocessor generation and get the real code from the preprocessor output. Then we can all see what that macro expands to. By making macros, you are in effect hiding the code, and what that macro expands to is the whole ballgame.
That is one of the first things you should have done -- see exactly what you are attempting to compile.
Regards,
Paul McKenzie
Re: Problem with explicit instantiation
Paul:
Thanks again for your help.
Finally I've been able to find the error. The key has been your advice " or turn on the preprocessor generation and get the real code from the preprocessor output".
The question was that the macro does not expanded exactly as I expected.
Cheers
Old newbie.