www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can templated functions be used in interfaces?

reply "Gary Willoughby" <dev nomad.so> writes:
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
next sibling parent reply "Gary Willoughby" <dev nomad.so> writes:
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
parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
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
prev sibling parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
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
parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
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