www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template matches more than one template declaration error when trying

reply solidstate1991 <laszloszeremi outlook.com> writes:
After some refactoring, there are four functions sharing the same 
name (technically four, but LDC didn't complain about them):

 nogc void blitter(T)(T* src, T* dest, size_t length){...}

and

 nogc void blitter(T)(T* src, T* dest, size_t length, T* 
mask){...}

I need the first one, but at compilation time I get the following 
error:

pixelperfectengine\src\PixelPerfectEngine\graphics\layers.d(61,30): Error:
template CPUblit.composing.blitter matches more than one template declaration:
..\..\..\AppData\Local\dub\packages\cpublit-0.2.3\cpublit\src\CPUblit\c
mposing.d(2006,19):     blitter(T)(T* src, T* dest, size_t length)
and
..\..\..\AppData\Local\dub\packages\cpublit-0.2.3\cpublit\src\CPUblit\c
mposing.d(2274,19):     blitter(T)(T* src, T* dest, size_t length, T* mask)
Nov 30 2018
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Dec 01, 2018 at 01:17:55AM +0000, solidstate1991 via
Digitalmars-d-learn wrote:
 After some refactoring, there are four functions sharing the same name
 (technically four, but LDC didn't complain about them):
 
  nogc void blitter(T)(T* src, T* dest, size_t length){...}
 
 and
 
  nogc void blitter(T)(T* src, T* dest, size_t length, T* mask){...}
 
 I need the first one, but at compilation time I get the following
 error:
 
 pixelperfectengine\src\PixelPerfectEngine\graphics\layers.d(61,30): Error:
template CPUblit.composing.blitter matches more than one template declaration:
 ..\..\..\AppData\Local\dub\packages\cpublit-0.2.3\cpublit\src\CPUblit\c
mposing.d(2006,19):     blitter(T)(T* src, T* dest, size_t length)
 and
 ..\..\..\AppData\Local\dub\packages\cpublit-0.2.3\cpublit\src\CPUblit\c
mposing.d(2274,19):     blitter(T)(T* src, T* dest, size_t length, T* mask)
For non-template overloaded functions, you can get the address by casting the function pointer, e.g.: void fun(int size) { writeln("1"); } void fun(int size, float z) { writeln("2"); } auto p1 = cast(void function(int)) &fun; auto p2 = cast(void function(int, float)) &fun; auto p3 = cast(void function(int, string)) &fun; p1(0); // prints "1" p2(0, 0f); // prints "2" p3(0, ""); // prints "1" (!) It's sorta weird when the cast doesn't match any overload; the compiler seems to just arbitrarily select the first one. However, for template functions, casting isn't enough; you need __traits(getOverloads): alias ovs = __traits(getOverloads, myModule, "gun", true); foreach (ov; ovs) { writeln(ov.stringof); } prints: gun(T)(T t, int size) gun(T)(T t, int size, float z) But actually coaxing the address out of the function is rather ugly: // These don't work: //auto q = &ovs[0]!int; //auto q = &(ovs[0]!int); //auto q = &(ovs[0])!int; // ... etc. // But this does: alias ov1 = ovs[1]; auto q = &ov1!int; q(0, 1, 1f); // prints "4" However, there appears to be a bug: if you try to access the first overload, it doesn't work again! // But this does: alias ov0 = ovs[0]; // NG: compile error! auto q = &ov0!int; q(0, 1, 1f); Sounds like a compiler bug should be filed. :-/ I tried to hack it by using AliasSeq to insert a dummy first element to the sequence then using [1] to access the first overload, but got the same error. I guess internally somehow the compiler isn't treating the first overload case correctly, independently of its position in the tuple / AliasSeq. T -- Nearly all men can stand adversity, but if you want to test a man's character, give him power. -- Abraham Lincoln
Nov 30 2018