www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Retrieve the return type of the current function

reply learner <learner nomail.com> writes:
Good morning,

Is it possible something like this?

```
int foo() {

     __traits(some_trait, some_generic_this) theInt = 0;
```

I mean, without using the function name in the body, like 
ReturnType!foo ?
May 05 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 5 May 2020 at 16:36:48 UTC, learner wrote:
 I mean, without using the function name in the body, like 
 ReturnType!foo ?
even easier: typeof(return)
May 05 2020
parent reply learner <learner nomail.com> writes:
On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote:

 typeof(return)
Thank you, that was indeed easy! Is it possible to retrieve also the caller return type? Something like: ``` int foo() { return magic(); } auto magic(maybesomedefaulttemplateargs = ??)() { alias R = __traits(???); // --> int! } ``` Mixin templates maybe?
May 05 2020
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, May 5, 2020 11:11:53 AM MDT learner via Digitalmars-d-learn 
wrote:
 On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote:
 typeof(return)
Thank you, that was indeed easy! Is it possible to retrieve also the caller return type? Something like: ``` int foo() { return magic(); } auto magic(maybesomedefaulttemplateargs = ??)() { alias R = __traits(???); // --> int! } ``` Mixin templates maybe?
A function is compiled completely independently of where it's used, and it's the same regardless of where it's used. So, it won't ever have access to any information about where it's called unless it's explicitly given that information. A function template will be compiled differently depending on its template arguments, but that still doesn't depend on the caller at all beyond what it explicitly passes to the function, and if the same instantiation is used in multiple places, then that caller will use exactly the same function regardless of whether the callers are doing anything even vaguely similar with it. So, if you want a function to have any kind of information about its caller, then you're going to have to either explicitly give it that information via a template argument or outright generate a different function with a string mixin every time you use it. So, you could do something like auto foo(T)(int i) { ... } string bar(string s, int i) { return!string(i); } or string bar(string s, int i) { return!(typeof(return))(i); } but you're not going to be have foo figure out anything about its caller on its own. - Jonathan M Davis
May 05 2020
prev sibling next sibling parent reply Meta <jared771 gmail.com> writes:
On Tuesday, 5 May 2020 at 17:11:53 UTC, learner wrote:
 On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote:

 typeof(return)
Thank you, that was indeed easy! Is it possible to retrieve also the caller return type? Something like: ``` int foo() { return magic(); } auto magic(maybesomedefaulttemplateargs = ??)() { alias R = __traits(???); // --> int! } ``` Mixin templates maybe?
You *can* use mixin templates to access the caller's scope, which means typeof(return) will refer to the caller's return type, instead of the callee's. However, there's no way to both mixin and call the mixin template in a single line, so it's not DRY: int foo() { mixin magic; return magic(); } mixin template magic() { alias CallerRet = typeof(return); CallerRet magic() { return CallerRet.init; } } void main() { foo(); } Maybe somebody else knows a way to get around having to first mixin magic.
May 05 2020
parent Meta <jared771 gmail.com> writes:
On Tuesday, 5 May 2020 at 18:19:00 UTC, Meta wrote:
 mixin template magic()
 {
     alias CallerRet = typeof(return);
     CallerRet magic()
     {
         return CallerRet.init;
     }
 }
Small edit: you can remove the "CallerRet" alias by doing the following: mixin template magic() { typeof(return) magic() { return typeof(return).init; } } Though I wouldn't really recommend it as it's very confusing, IMO. This works because "typeof(return)" in the return position here refers to the caller's scope, while "typeof(return)" inside the function refer's to the function's scope.
May 05 2020
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2020-05-05 19:11, learner wrote:
 On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote:
 
 typeof(return)
Thank you, that was indeed easy! Is it possible to retrieve also the caller return type? Something like:
Yes, kind of: void foo(string caller = __FUNCTION__)() { import std.traits : ReturnType; alias R = ReturnType!(mixin(caller)); static assert(is(R == int)); } int bar() { foo(); return 0; } -- /Jacob Carlborg
May 06 2020
parent learner <learner nomail.com> writes:
On Wednesday, 6 May 2020 at 08:04:16 UTC, Jacob Carlborg wrote:
 On 2020-05-05 19:11, learner wrote:
 On Tuesday, 5 May 2020 at 16:41:06 UTC, Adam D. Ruppe wrote:
 
 typeof(return)
Thank you, that was indeed easy! Is it possible to retrieve also the caller return type? Something like:
Yes, kind of: void foo(string caller = __FUNCTION__)() { import std.traits : ReturnType; alias R = ReturnType!(mixin(caller)); static assert(is(R == int)); } int bar() { foo(); return 0; }
Awesome and beautiful, thank you!
May 06 2020