digitalmars.D.learn - Referencing an overloaded function
- John (18/18) Mar 24 2012 Is there any way to refer to a specific function overload?
- Philippe Sigaud (21/22) Mar 24 2012 You can use __traits(getOverloads, aggregate, "member") to get all
- John (2/20) Mar 24 2012 That's exactly what I was looking for. Thanks.
- Mantis (17/34) Mar 24 2012 import std.stdio;
- Artur Skawina (8/61) Mar 24 2012 would work.
- Artur Skawina (7/24) Mar 24 2012 and I should actually test the code before posting, even when the compil...
- Philippe Sigaud (7/8) Mar 24 2012 "foo")) {
- Timon Gehr (13/19) Mar 24 2012 You can get the parent of an alias. The following template finds all
- Artur Skawina (10/31) Mar 24 2012 Yeah, your version does not work with my old GDC either (stringof return...
- Timon Gehr (2/35) Mar 24 2012
Is there any way to refer to a specific function overload? For example: import std.stdio; import std.traits; void foo() {} void foo(int x) {} void main() { writeln(foo.mangleof); writeln(ParameterTypeTuple!(foo).stringof); } Both of these statements always refer to the first matching function. If I change the order of declarations for foo, the results change. Is there a way to reference the second overload in this example? I can use a function pointer with ParameterTypeTuple to get the correct result, but something like mangleof won't work, since that will return the mangle of the local function pointer instead of the original function.
Mar 24 2012
On Sat, Mar 24, 2012 at 13:13, John <nospam unavailable.com> wrote:Is there any way to refer to a specific function overload?You can use __traits(getOverloads, aggregate, "member") to get all overloads of member aggregate.member. Where an aggregate is a class, a struct or a module. module pack.mod; // needs to be XXX.YYY for __traits to work void foo() {} void foo(int x) {} template Alias(A...) { alias A Alias;} void main() { // The Alias!( ) trick is needed to work around a limitation in alias X Y grammar // __traits() is not accepted in an alias: alias __traits(getOverloads, X, "Y") OV_XY; does not work alias Alias!(__traits(getOverloads, pack.mod, "foo")) OV; // OV is a tuple holding all the different foo's foreach(i, ov; OV) alias OV[1] intFoo; // void foo(int x) {} intFoo(1); // calls void foo(int x) {} }
Mar 24 2012
On Saturday, 24 March 2012 at 13:59:30 UTC, Philippe Sigaud wrote:module pack.mod; // needs to be XXX.YYY for __traits to work void foo() {} void foo(int x) {} template Alias(A...) { alias A Alias;} void main() { // The Alias!( ) trick is needed to work around a limitation in alias X Y grammar // __traits() is not accepted in an alias: alias __traits(getOverloads, X, "Y") OV_XY; does not work alias Alias!(__traits(getOverloads, pack.mod, "foo")) OV; // OV is a tuple holding all the different foo's foreach(i, ov; OV) alias OV[1] intFoo; // void foo(int x) {} intFoo(1); // calls void foo(int x) {} }That's exactly what I was looking for. Thanks.
Mar 24 2012
24.03.2012 14:13, John написал:Is there any way to refer to a specific function overload? For example: import std.stdio; import std.traits; void foo() {} void foo(int x) {} void main() { writeln(foo.mangleof); writeln(ParameterTypeTuple!(foo).stringof); } Both of these statements always refer to the first matching function. If I change the order of declarations for foo, the results change. Is there a way to reference the second overload in this example? I can use a function pointer with ParameterTypeTuple to get the correct result, but something like mangleof won't work, since that will return the mangle of the local function pointer instead of the original function.import std.stdio; import std.traits; void foo() { writeln( "void" ); } void foo( int x ) { writeln( x ); } template getOverload( alias func, A... ) { void function(A) getOverload = &func; } void main() { writeln( getOverload!(foo, int).mangleof ); writeln( ParameterTypeTuple!(getOverload!(foo, int)).stringof ); getOverload!(foo, int)(42); getOverload!(foo)(); } Will not hold for return types other than void, there may be some generic workaround (of course, you can pass return type as tempate parameter).
Mar 24 2012
On 03/24/12 15:39, Mantis wrote:24.03.2012 14:13, John написал:Something likeIs there any way to refer to a specific function overload? For example: import std.stdio; import std.traits; void foo() {} void foo(int x) {} void main() { writeln(foo.mangleof); writeln(ParameterTypeTuple!(foo).stringof); } Both of these statements always refer to the first matching function. If I change the order of declarations for foo, the results change. Is there a way to reference the second overload in this example? I can use a function pointer with ParameterTypeTuple to get the correct result, but something like mangleof won't work, since that will return the mangle of the local function pointer instead of the original function.import std.stdio; import std.traits; void foo() { writeln( "void" ); } void foo( int x ) { writeln( x ); } template getOverload( alias func, A... ) { void function(A) getOverload = &func; } void main() { writeln( getOverload!(foo, int).mangleof ); writeln( ParameterTypeTuple!(getOverload!(foo, int)).stringof ); getOverload!(foo, int)(42); getOverload!(foo)(); } Will not hold for return types other than void, there may be some generic workaround (of course, you can pass return type as tempate parameter).auto getOverload(alias func, A...)(A a) { typeof(foo(a)) function(A) getOverload = &func; }would work. The problem with that solution is however that .mangleof will return the wrong name. This:foreach (f; __traits(getOverloads, __traits(parent, main), "foo")) { static if (is(ParameterTypeTuple!f==TypeTuple!(int))) { writeln(f.mangleof); writeln(ParameterTypeTuple!(f).stringof); //writeln(typeof(f).stringof); //f(42); //etc } }will do the right thing when you need the original name of foo(int). artur
Mar 24 2012
On 03/24/12 18:07, Artur Skawina wrote:On 03/24/12 15:39, Mantis wrote:Of course that should have been something more like:Will not hold for return types other than void, there may be some generic workaround (of course, you can pass return type as tempate parameter).Something likeauto getOverload(alias func, A...)(A a) { typeof(foo(a)) function(A) getOverload = &func; }would work. The problem with that solution is however that .mangleof will return the wrong name.template tr(A...) { extern A tr; } template getOverload(alias func, A...) { typeof(foo(tr!A)) function(A) getOverload = &func; }and I should actually test the code before posting, even when the compiler tries to make things difficult (Error: functions cannot return a tuple). ;) While this version works now, it's still prevents getting the correct mangled function name - the getOverloads loop approach gets that right. artur
Mar 24 2012
On Sat, Mar 24, 2012 at 18:07, Artur Skawina <art.08.09 gmail.com> wrote:"foo")) { Hey, this ^^^^^^^^^^^^^^^^^^^^^^ it's a way to get the current module, right? Nice trick, I didn't think of = this. Its limitation is it won't work outside the 'main() {}' module.=C2=A0 =C2=A0 foreach (f; __traits(getOverloads, __traits(parent, main),=
Mar 24 2012
On 03/24/2012 09:07 PM, Philippe Sigaud wrote:On Sat, Mar 24, 2012 at 18:07, Artur Skawina<art.08.09 gmail.com> wrote:You can get the parent of an alias. The following template finds all overloads of a given symbol: template ID(T...){alias T ID;} template getOverloads(alias f){ enum fname = f.stringof[0..f.stringof.indexOf("(")]; alias ID!(__traits(getOverloads, __traits(parent, f), fname)) getOverloads; } I think this should go into std.traits, as soon as it works. (DMD is buggy when it comes to taking the .stringof of a function. It misinterprets it as a property function call in some cases but not in others. Messy.)Hey, this ^^^^^^^^^^^^^^^^^^^^^^ it's a way to get the current module, right? Nice trick, I didn't think of this. Its limitation is it won't work outside the 'main() {}' module.foreach (f; __traits(getOverloads, __traits(parent, main), "foo")) {
Mar 24 2012
On 03/24/12 23:10, Timon Gehr wrote:On 03/24/2012 09:07 PM, Philippe Sigaud wrote:Yeah, your version does not work with my old GDC either (stringof returns really weird things here...); this one works: template ID(T...) { alias T ID; } template getOverloads(alias F) { alias ID!(__traits(getOverloads, __traits(parent, F), __traits(identifier, F))) getOverloads; } and looks obvious enough; it would be nice to get rid of that extra ID step, though. arturOn Sat, Mar 24, 2012 at 18:07, Artur Skawina<art.08.09 gmail.com> wrote:You can get the parent of an alias. The following template finds all overloads of a given symbol: template ID(T...){alias T ID;} template getOverloads(alias f){ enum fname = f.stringof[0..f.stringof.indexOf("(")]; alias ID!(__traits(getOverloads, __traits(parent, f), fname)) getOverloads; } I think this should go into std.traits, as soon as it works. (DMD is buggy when it comes to taking the .stringof of a function. It misinterprets it as a property function call in some cases but not in others. Messy.)Hey, this ^^^^^^^^^^^^^^^^^^^^^^ it's a way to get the current module, right? Nice trick, I didn't think of this. Its limitation is it won't work outside the 'main() {}' module.foreach (f; __traits(getOverloads, __traits(parent, main), "foo")) {
Mar 24 2012
On 03/25/2012 12:34 AM, Artur Skawina wrote:On 03/24/12 23:10, Timon Gehr wrote:Nice one.On 03/24/2012 09:07 PM, Philippe Sigaud wrote:Yeah, your version does not work with my old GDC either (stringof returns really weird things here...); this one works: template ID(T...) { alias T ID; } template getOverloads(alias F) { alias ID!(__traits(getOverloads, __traits(parent, F), __traits(identifier, F)))On Sat, Mar 24, 2012 at 18:07, Artur Skawina<art.08.09 gmail.com> wrote:You can get the parent of an alias. The following template finds all overloads of a given symbol: template ID(T...){alias T ID;} template getOverloads(alias f){ enum fname = f.stringof[0..f.stringof.indexOf("(")]; alias ID!(__traits(getOverloads, __traits(parent, f), fname)) getOverloads; } I think this should go into std.traits, as soon as it works. (DMD is buggy when it comes to taking the .stringof of a function. It misinterprets it as a property function call in some cases but not in others. Messy.)Hey, this ^^^^^^^^^^^^^^^^^^^^^^ it's a way to get the current module, right? Nice trick, I didn't think of this. Its limitation is it won't work outside the 'main() {}' module.foreach (f; __traits(getOverloads, __traits(parent, main), "foo")) {getOverloads; } and looks obvious enough; it would be nice to get rid of that extra ID step, though. artur
Mar 24 2012