I'm trying to port my own lib from Visual Studio to g++ on GNU/Linux, and I'm getting some problems with template compilation. Indeed, in Visual C++, templates are generated only when they are explicitly used in the code, while it seems (from my errors) that g++ evaluates the contents of templates before they are first used. This results in the following error:
error: incomplete type ‘X’ used in nested name specifier
... because I include some classes after the template code, rather than before. I am doing this due to a cross-use conflict.
To sum it seems that Visual C++ does not attempt to resolve templates' content on use, and g++ does resolution as soon as possible.
class MyClass;
template<class _Ty>
void func(MyClass* a_pArg)
{
a_pArg->foo();
};
(_Ty isn't used but it doesn't matter, it's just to explain the problem)
In that case Visual C++ would compile (even if MyClass
isn't predeclared), while g++ will not, because MyClass
hasn't been completely declared.
Is there a way to tell g++ to instantiate templates only on use?
As it was indicated in another answer, gcc is correct looking up non-dependent names in the first lookup phase, and VC++ shifts most checks to the second phase (which is incorrect). In order to fix your code, you don't need to search for some broken version of gcc. You need to separate the declaration and implementation (at least for non-dependent names). Using your example,
// provide declarations
class MyClass;
template<class T>
void func(MyClass* a_pArg);
// provide definition of MyClass
class MyClass
{
// watever
};
// provide definition of func
template<class T>
void func(MyClass* a_pArg);
{
a_pArg->foo();
};
If you are willing to use CLang instead of gcc, CLang support the -fdelayed-template
(dedicated to perform template instantiation at the end of the parsing) implied by -fms-extensions
option specifically designed to compile MSVC code (and numerous quirks).
According to Francois Pichet, who is leading CLang effort to fully compile MSVC code (and actually doing most of it), CLang should be able to parse all of MFC code in about 2 to 3 months, with only a couple of non-trivial issues remaining. Already most of MFC is correctly interpreted (ie, interpreted as VC++ does).
No, that's the way two-phase lookup works. MSVC implements it wrong, it nearly skips the first phase, which parses the template at the point of definition. MSVC only does some basic syntax checking here. In the second phase, on actual use of the template, the dependent names should only be inspected. MSVC does all kind of parsing here instead. GCC implements the two-phase lookup correctly.
In your case, since MyClass
isn't a template parameter, it can inspect it in phase one. You just need to include your class header before that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With