Topic: virtual member template
Author: Frederic Tran_Minh <Frederic.Tran_Minh@sophia.inria.fr>
Date: Fri, 13 Jul 2001 15:40:30 GMT Raw View
Hi all,
"A member function template shall not be virtual"
ANSI C++, 14.5.2.3
WHY ???
Ex:
class A {
// ...
};
template <class T> // the problem rises also if not template here
// but the conversion matter is a good example
class B : public A {
// ...
template <class U>
virtual void convert(const B<U>& b); //illegal
// ...
};
Thanks
Fred
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Steve Clamage <clamage@eng.sun.com>
Date: Fri, 13 Jul 2001 18:08:13 GMT Raw View
On Fri, 13 Jul 2001, Frederic Tran_Minh wrote:
> "A member function template shall not be virtual"
> ANSI C++, 14.5.2.3
>
> WHY ???
>
Newsgroup comp.lang.c++.moderated has a long thread, still going, on
this exact question.
The short answer is that Stroustrup judged that the difficulty of
implementation and resulting reduced run-time performance was not
justified by the benefits of the feature. The C++ committee agreed.
Under current language rules, the compiler sees the entire list of
virtual function in the class definition, and the entire class
definition must be visible at the point of any use of virtual functions.
In the usual, efficient, implementation of virtual functions, the
compiler assigns an index number to each virtual function, and
creates a table of virtual function addresses (the "vtable"). A call
to a virtual function is handled by an indirect call via the index
in the vtable.
For derived classes and hierarchies, the compiler sees everything
it needs to know to number all the virtual functions and maintain
correpondence of function indexes throughout the hierarchy. That is,
a call to virtual function foo via a pointer to the base class
must resolve to the correct overriding function if the pointer
refers to a derived class. Thus, function foo must have the same
index in every vtable in the hierarchy.
If a virtual member function could be a template function, the compiler
cannot know how many instances of that template will be generated in
the entire program. The number of possible instances of the function
is effectively unbounded. Different translation units could use
the same or different instances of the template.
The C++ implementation would have to defer until final program link
time the assignment of indexes to the template instances, somehow
matching up the indexes of specific instances in different translation
units, and ajusting the calls accordingly.
In case the problem isn't clear, consider this example:
myclass.h:
----------
class myclass {
public:
virtual template<class T> T foo(T t);
};
file1.cc:
---------
int f1(myclass* m, int i) { return m->foo(i); }
double f2(myclass* m, double x) { return m->foo(x); }
file2.cc:
---------
char* f3(myclass* m, char* p) { return m->foo(p); }
int f4(myclass* m, int i) { return m->foo(i); }
When compiling file1, the compiler must generate virtual calls to the
generated instances foo<int> and foo<double>. For file2, the virtual
calls are for foo<char*> and foo<int>. In each file, the calls to
foo<int> must resolve to the same function.
But wait, there's more!
der.h
-----
class der : public myclass {
public:
virtual template<class T> T foo(T t); // overrides myclass::foo
};
For each class derived from foo, the corresponding virtual functions
must be matched, among all classes in the hierarchy. Suppose that
der::foo<long> is needed, but there is no reference to myclass::foo<long>
anywhere in the program. The compiler must make an index for
myclass::foo<long> in the table of myclass::foo instances to keep indexes
matching.
But wait, there's more!
Class myclass could be part of any number of disjoint class hierarchies.
All of the indexes for myclass::foo must be matched with all overrides
in all derived classes in all hierarchies.
But wait, there's more!
Suppose a dynamic library is loaded after program start, and it contains
an instance of myclass::foo not present anywhere else in the program. The
vtables, and references to them, would have to be adjustable at run time.
Worse, suppose the dynamic library contains a new instance a derived-class
instance, requiring also the adjustment of each of its base class tables.
---
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Carl Daniel" <cpdaniel@nospam.pacbell.net>
Date: Mon, 16 Jul 2001 17:08:30 GMT Raw View
"Steve Clamage" <clamage@eng.sun.com> wrote in message
news:Pine.SOL.3.96.1010713100146.27128A-100000@taumet...
> On Fri, 13 Jul 2001, Frederic Tran_Minh wrote:
> > "A member function template shall not be virtual"
> > ANSI C++, 14.5.2.3
> >
> > WHY ???
> >
>
> Newsgroup comp.lang.c++.moderated has a long thread, still going, on
> this exact question.
>
[Major snip of excellent summary]
Is this in the FAQ? If not, I nominate Steve's text to be added thereto
posthaste! It seems to be a popular question lately...
-cd
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]