digitalmars.D.learn - Can templated functions be used in interfaces?
- Gary Willoughby (26/26) Jul 11 2013 I have an interface like this:
- Gary Willoughby (3/3) Jul 11 2013 Also i've noticed that the compiler doesn't complain if templated
- Jakob Ovrum (33/36) Jul 11 2013 What you've done is declared a non-virtual member of the
- Jakob Ovrum (21/22) Jul 11 2013 Function templates cannot be virtual. You're allowed to declare
- Maxim Fomin (8/21) Jul 11 2013 It is possible in current implementation to split template
I have an interface like this: interface IAccessor { public ResultSet getCacheData(); public bool persist(T)(ref T[] collection); } Then i'm composing an object constraining via that interface: ... private IAccessor _accessor public void setAccessor(IAccessor accessor) { this._accessor = accessor; } ... When i call the method like this: auto x = this._accessor.persist!User(collection); I get this error: Undefined symbols for architecture x86_64: "_D7storage9iaccessor9IAccessor29__T7persistTS4data4user4UserZ7persistMFKA 4data4user4UserZb", referenced from: _D5logic13userprocessor13UserProcessor15persistNewUsersMFZv in main.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status Any idea what i'm doing wrong?
Jul 11 2013
Also i've noticed that the compiler doesn't complain if templated functions are not implemented in the classes that implement the interface, which is wrong!
Jul 11 2013
On Thursday, 11 July 2013 at 12:00:20 UTC, Gary Willoughby wrote:Also i've noticed that the compiler doesn't complain if templated functions are not implemented in the classes that implement the interface, which is wrong!What you've done is declared a non-virtual member of the interface without a definition. This is, in itself, completely fine: /* myinterface.di */ interface Foo { void bar(); // virtual member; implemented in derived classes final void foo(); // Declaration without definition, as this is a D interface module (equivalent of a C or C++ header file) } /* myinterface.d */ interface Foo { void bar(); // virtual member; implemented in derived classes final void foo() { // Defines 'Foo.foo' } } The above example displays useful behaviour and is thus allowed, but with templated functions, the declaration and definition may not be separated in this way, so it only makes sense for non-templated functions. If you try to link an executable using code that uses the definition-less declarations (D interface module), *without providing the linker with code that implements (defines) those declarations*, you will get a linker error like the one you did. What you did was instantiate a function template without a definition then trying to link an executable without that code, giving you the error. It doesn't actually make any sense to try to separate templated function declarations from their definitions, so the code should be refused at compile-time.
Jul 11 2013
On Thursday, 11 July 2013 at 11:56:16 UTC, Gary Willoughby wrote:Any idea what i'm doing wrong?Function templates cannot be virtual. You're allowed to declare non-virtual members of interfaces, but they must be defined. That means static functions, final functions and function templates can be declared in interfaces as long as they are defined. This is a feature of D. However, in my opinion, it's a bug that you're allowed to declare a function template (when using the shortcut syntax) without defining it, whether in an interface or not. This is a rather natural bug though, due to the nature of function templates: void a()(); is equivalent of: template a() { void a(); } Perhaps it makes sense to allow the declaration without definition when the template and function are explicitly separated (can anyone think of a case where this is useful? Maybe mixin-related?), but when using the former syntax - the function template syntax - I don't think it makes any sense. Whether or not function templates in general should be declarable without a definition, it's definitely a bug that you can do it in an interface.
Jul 11 2013
On Thursday, 11 July 2013 at 12:03:10 UTC, Jakob Ovrum wrote:However, in my opinion, it's a bug that you're allowed to declare a function template (when using the shortcut syntax) without defining it, whether in an interface or not. This is a rather natural bug though, due to the nature of function templates: void a()(); is equivalent of: template a() { void a(); } Perhaps it makes sense to allow the declaration without definition when the template and function are explicitly separated (can anyone think of a case where this is useful? Maybe mixin-related?), but when using the former syntax - the function template syntax - I don't think it makes any sense.It is possible in current implementation to split template declaration and definition in different modules but in such case list of potential template arguments is limited. Disabling this option in general would disable D ability to hide template implementation (like libraries and external functions). But in this particular case I agree that this should be an error like in situation with static functions.
Jul 11 2013