windows - Is it valid for a C++ compiler to implicitly instantiate ALL member functions of a template class? -


suppose have public class , private implementation class (e.g. pimpl pattern), , wish wrap private class template smart pointer class checked delete, follows:

publicclass.h

class privateclass;  // simple smart pointer checked delete template<class x> class demo_ptr { public:     demo_ptr (x* p) : the_p(p) { }     ~demo_ptr () {         // boost::checked_delete: don't allow compilation of incomplete type         typedef char type_must_be_complete[ sizeof(x)? 1: -1 ];         (void) sizeof(type_must_be_complete);         delete the_p;     } private:     x* the_p; };  // public-facing class wishes wrap private implementation guts class publicclass { public:     publicclass();     ~publicclass();  private:     demo_ptr<privateclass> pvt; }; 

publicclass.cpp

#include "publicclass.h"  class privateclass { public:     // implementation stuff goes here...     privateclass() {} }; //--------------------------------------------------------------------------- publicclass::publicclass() : pvt(new privateclass()) {}  publicclass::~publicclass() {} 

main.cpp

#include "publicclass.h"  int main() {     publicclass *test = new publicclass();     delete test;     return 0; } 

this code compiles on visual c++ 2008, fails compile on old version of c++ builder. in particular, main.cpp not compile because demo_ptr<privateclass>::~demo_ptr being instantiated main.cpp, , destructor won't compile because can't sizeof on incomplete type privateclass. clearly, not useful compiler instantiating ~demo_ptr in consuming main.cpp, since never able generate sensible implementation (seeing how ~privateclass not accessible). (publicclass.cpp compiles fine on tested compilers.)

my question is: c++ standard implicit instantiation of template class's member functions? might 1 of following? in particular, has changed on years?

  • if template class used, member functions of class should implicitly instantiated - whether used or not?
  • or: template class functions should implicitly instantiated 1 @ time if used. if particular template class function isn't used, shouldn't implicitly instantiated - if other template class functions used , instantiated.

it seems clear second case case today because same pattern used pimpl , unique_ptr checked delete, maybe not case in past? first case acceptable compiler behavior in past?

or in other words, compiler buggy, or did accurately follow c++98 standard, , standard changed on years?

(fun fact: if remove checked delete in c++ builder, , have function inlining turned off, project happily compile. publicclass.obj contain correct ~demo_ptr implementation, , main.obj contain incorrect ~demo_ptr implementation undefined behavior. function used depend on order in these files fed linker.)

update: due compiler bug, noted andy prowl, still not fixed in c++ builder xe8. i've reported bug embarcadero: bcc32 compiler causes undefined behavior when using std::auto_ptr pimpl idiom because template instantiation rules not follow c++ spec

if template class used, member functions of class should implicitly instantiated - whether used or not?

no, not case. per paragraph 14.7.1/10 of c++11 standard (and paragraph 14.7.1/9 of c++03 standard) specifies:

an implementation shall not implicitly instantiate function template, member template, non-virtual member function, member class, or static data member of class template not require instantiation.

as when instantiation required, paragraph 14.7.1/2 specifies:

unless member of class template or member template has been explicitly instantiated or explicitly specialized, specialization of member implicitly instantiated when specialization referenced in context requires member definition exist; [...]

this not case if member function never referenced.


unfortunately, can't provide official reference on rules before c++03, best of knowledge same "lazy" instantiation mechanism adopted in c++98.


Comments

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -