Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicit template declaration/definition in VS 2012

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?

like image 812
Jeff Gates Avatar asked May 28 '13 17:05

Jeff Gates


People also ask

What is explicit template instantiation?

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.

How do I instantiate a template in C ++?

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.

Is it necessary to instantiate a template?

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).

How many times is the template class instantiation?

cpp, there are two instantiations: template class B<int> and B<float>.


3 Answers

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.

like image 112
Andy Prowl Avatar answered Sep 23 '22 21:09

Andy Prowl


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.

like image 45
user2497061 Avatar answered Sep 25 '22 21:09

user2497061


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.

like image 26
Colin Robertson Avatar answered Sep 25 '22 21:09

Colin Robertson