Using a valid member function of a STATIC class that cannot be set

I have the following code:

It compiles without problems in gcc-3.4, gcc-4.3, the Intel compiler, but does not work under MSVC9.

MSVC reports "using undefined type c_traits<C> when compiling a member function of a class template void foo<C>::go(void) with C = short.

That the compiler is trying to set an unused member function of an unused class, because this class is simply not used at all.

I can get around the problem by specializing in whole foo classes, rather than specializing in its member function. But the fact that specialization of the whole class is a little problematic for me for various reasons.

The big question is: what is right?

  • Is my code wrong and the gcc and intel compiler just ignores the problem because they don't install foo completely, or
  • The code is correct, and is it an MSVC9 (VC 2008) error that tries to install unused member functions?

The code:

 class base_foo { public: virtual void go() {}; virtual ~base_foo() {} }; template<typename C> struct c_traits; template<> struct c_traits<int> { typedef unsigned int_type; }; template<typename C> class foo : public base_foo { public: static base_foo *create() { return new foo<C>(); } virtual void go() { typedef typename c_traits<C>::int_type int_type; int_type i; i=1; } }; template<> base_foo *foo<short>::create() { return new base_foo(); } int main() { base_foo *a; a=foo<short>::create(); delete a; a=foo<int>::create(); delete a; } 
+6
c ++ visual-c ++ specialization
source share
2 answers

Both compilers are right here; behavior for your case is not specified. ISO C ++ 14.7.1 [temp.inst] / 9:

An implementation should not implicitly create a function template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation. It is not known whether the implementation implicitly implements an instance of a virtual member function of a class template if the virtual member function were not created otherwise.

The reasons for this are quite simple: a virtual function requires a record in the vtable format, and with virtual dispatching it can be difficult to determine whether a given virtual function is actually called or not. Thus, ISO C ++ allows compilers to perform such advanced analysis to generate less code, but does not require them - therefore, as a C ++ programmer, you should always assume that all virtual functions will always be created.

+3
source share

Removing unused functions will occur when binding not to the compilation where you encountered your error. MSVC may not know which of all compilation modules compiles, who ultimately calls this method. He cannot know until the compilation is complete and until the connection occurs. Naturally, different compilers may be smarter about this, but I suspect this may be what is happening.

I suspect your specific compiler errors sound as if it is caused by the fact that you specified only declared

 template<typename C> struct c_traits; 

You did not fully define the class. You tried something simple:

 template<typename C> struct c_traits { // some default/dummy int type }; 

I suspect that this will at least stop the compiler from complaining.

EDIT

this is usually wrong for class templates. The functions of the members of the class templates should not be compiled (and any errors in their bodies should not be triggered) if they are not created

In this case, the template is created in the form:

  foo<short> 

The compiler will consider this as any other class for which methods have the potential for external communication. I have not heard any special language rule saying that external communication does not apply to templates ...?

+1
source share

All Articles