Why aren't virtual templated functions allowed?
ie:
would produce an errorCode:template <typename T, typename W> virtual void Foo::bar(T& t, const W& w) { }
Why aren't virtual templated functions allowed?
ie:
would produce an errorCode:template <typename T, typename W> virtual void Foo::bar(T& t, const W& w) { }
OK?!Code:>why is it impossible to declare virtual member templates? > > class foo { virtual template<class C> void bar(C); // error }; > > > Somebody tell me, it is impossible for the compiler to resolve, but I thought, the > compiler should generate a function for each type used by this class and any > derrived ones... so if I call to foo::bar(int) later one, the compiler could > generate an instance of bar(int) for class foo and each class derriving from it and > redefining the template? The signature of every virtual function must exist when something inherits the class owning those virtual functions. Functions overload by signature. But the above function by definition can't know every virtual that could exist at inheritance time. Mechanically, virtual functions behave As If every object with them had a pointer to a table of jumps into function bodies. But the compiler has no way to know how many potential overloads of that function may exist after linking, so it can't know how to write that table. This is an excuse - a smarter linker is conceivable. But it's why the Standard explicitely says that virtual template functions are not allowed.
I agree with much of that, but there's a more fundamental problem -- the size and layout of an object with a virtual templated function could not be known at compile time, only at link time (only the linker can see which instances were made over all compilation units). This would require drastic changes, not merely to the linker, but to the whole idea of compilation and linking.
During compilation, the compiler needs to know the complete contents and layout of each class in the compilation unit, and the contents and layout must not change from one compilation unit to another, or Very Bad Things would happen once linking happened. So each compilation unit would have to know every instance of the template, in ALL compilation units, and that breaks the whole idea of a compilation unit (which is that the compiler can only see one unit at a time).
Because of the ramifications, I doubt it will ever be possible. A smarter means of code generation could be constructed, but to allow this would break the most fundamental assumptions of the current compiler/linker model, and I doubt the standards committee would ever even consider throwing the entire compilation model out the window.
Last edited by Cat; 08-15-2003 at 01:57 PM.
On the other hand, they allowed the 'export' keyword, which is also hard to implement.
Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling
I have to disagree with you, Cat. After all, a compiler *will* generate functions with signatures corresponding to each template instantiation, so why not patching up the v-table in the meantime? But, then again, a virtual function serves as a guaranteed interface, so it doesn't really make sense to allow templated ones, come to think of it. So much for that.
Funny when your mind changes mid-post.
[edit]
What's up, Sang-Drax? Good to see you again.
[/edit]
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
It's not just about the addresses in the vtable, it's about the actual contents of the vtable themselves, and thus the size of the object itself that will change.
The linker would have to do a LOT of work, and not simple work either, to fix things.