The following code declares a template, declares an explicit instantiation definition, then declares an explicit instantiation declaration:
template <typename T>
T Double(T number)
{
return number * 2;
}
extern template int Double<int>(int); // declaration
template int Double<int>(int t); // definition
int main(int argc, char* argv[])
{
int n = Double(10);
return 0;
}
gives an error:
error C2929: 'int Double<int>(int)' : explicit instantiation; cannot explicitly force and suppress instantiation of template-class member
in Visual Studio 2012.
I'm under the impression from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm that this should be valid, since the definition follows the declaration.
Am I missing something?
C++ Templates Explicit instantiation An explicit instantiation definition creates and declares a concrete class, function, or variable from a template, without using it just yet. An explicit instantiation can be referenced from other translation units.
To instantiate a template class explicitly, follow the template keyword by a declaration (not definition) for the class, with the class identifier followed by the template arguments. template class Array<char>; template class String<19>; When you explicitly instantiate a class, all of its members are also instantiated.
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).
cpp, there are two instantiations: template class B<int> and B<float>.
Your program is well-formed. Paragraph 14.7.2/11 of the C++11 Standard specifies:
If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition in the same translation unit, the definition shall follow the declaration. [...]
Your program respects this constraint and does not break any other rule. Therefore, this qualifies as a bug in VC11.
It seems this issue was reported to Microsoft Connect 620017:
Posted by Microsoft on 12/3/2010 at 1:52 PM
Hello,
As you've noted, our implementation of extern templates does not conform to the C++-0x standard. We still have our old extension implementation. Although we don't have the resources to implement the C++-0x version of this feature for the next release of Visual Studio, conformance issues are a priority for us; we do currently intend to implement this feature in a future version of Visual Studio.
Thanks for taking the time to report this issue. We do appreciate it.
Jamie Eckman Visual C++ Team
That was from 2010, so by "next release" he meant VS2012.
This Visual C++ conformance bug is addressed in Visual Studio 2013, which is available here. This fix makes it possible to place extern template
declarations in header files to suppress template instantiation and still declare an explicit instantiation in one module, which can cut down on compilation time and code bloat. Reversing the statements (that is, an explicit instantiation request, followed by an extern template
declaration with the same template arguments) still causes error C2929, since it looks like you are now trying to suppress something you've already explicitly instantiated.
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