Short answer:
is(T == function) <t T is a functionisFunctionPointer!T T is a function pointer (not a delegate)isDelegate!T <isSomeFunction!T
Long answer:
A function is, well, a function.
auto func(int val) {...}
This is a piece of code with a name that you can call using that name. You give him arguments, he does everything he does and returns the result. You can call it, but you cannot convey it. To do this, you need a function pointer.
A function pointer is a pointer to a function. So, as int is int , and int* is a pointer to int , and int not a pointer to int , the function is not a pointer to a function. If you need a pointer to a function, you need a pointer to a function. The syntax is different from how it works with int , but it has the same concept.
A delegate is a pointer to a state function. So, for example, in
int foo(int value) { int bar() { return value + 5; } auto barDel = &bar; return barDel(); } void main() { auto fooFunc = &foo; }
foo is a function, bar is a nested function that has access to its outer region, and barDel is a delegate, because it is a state function pointer (the outer state in which bar has access to). If you move barDel to another function (or return it), you will get a closure (unless the passed function accepts a delegate for scope ), in which case this function ensures that the delegate does not leave its scope), because this state should be put in a heap so that it continues to exist, even if the call to the function from which its state originates is completed when it is called. funcFoo , on the other hand, is a function pointer, since foo has no external state. If bar were static , then barDel also be a function pointer, not a delegate, because bar would no longer have access to the function it is in (although its body would then need to be changed since it would no longer have access to value ).
Now for your example. Object.toString is a member function of Object . So this is a function. He is not related to him. Functions are never performed. His current signature
string toString();
But since it is a member function from Object , its signature really looks like
string toString(Object this);
this is passed to toString as an argument. It is not affiliated with toString . Therefore, &Object.toString not a delegate. It is just a pointer to a function. And Object.toString not a function pointer, so even if &Object.toString was a delegate, static assert(isDelegate!(typeof(Object.toString))) will still fail, because in order to be a delegate, it must be a function pointer, but it is not. This is a function.
Now, unfortunately, typeof(&Object.toString) is considered a string function() , not a string function(Object) , so using it to call toString with the actual Object takes a bit of work. It can be done, but I donβt remember how at the moment (and this is a bit ugly IIRC). But he would not be a delegate, regardless of the fact that no state was associated with him.
If you need a function with which you can pass an Object and call a member function call, you can do something like
auto obj = getObjectFromSomewhere(); auto func = function(Object obj){return obj.toString();}; auto result = func(obj);
If you want to associate an object with a member function and be able to call this member function on this object without having to pass the object around, then you simply transfer it to the delegate:
auto obj = getObjectFromSomewhere(); auto del = delegate(){return obj.toString();}; auto result = del();
This bit of code should summarize things and illustrate them well:
int foo(int value) { int bar() { return value + 5; } static assert( is(typeof(bar) == function)); static assert(!isFunctionPointer!(typeof(bar))); static assert(!isDelegate!(typeof(bar))); static assert( isSomeFunction!(typeof(bar))); auto barDel = &bar; static assert(!is(typeof(barDel) == function)); static assert(!isFunctionPointer!(typeof(barDel))); static assert( isDelegate!(typeof(barDel))); static assert( isSomeFunction!(typeof(barDel))); static int boz(int i) { return i + 2; } static assert( is(typeof(boz) == function)); static assert(!isFunctionPointer!(typeof(boz))); static assert(!isDelegate!(typeof(boz))); static assert(isSomeFunction!(typeof(boz))); auto bozFunc = &boz; static assert(!is(typeof(bozFunc) == function)); static assert( isFunctionPointer!(typeof(bozFunc))); static assert(!isDelegate!(typeof(bozFunc))); static assert( isSomeFunction!(typeof(bozFunc))); return boz(bar()); } static assert( is(typeof(foo) == function)); static assert(!isFunctionPointer!(typeof(foo))); static assert(!isDelegate!(typeof(foo))); static assert( isSomeFunction!(typeof(foo))); void main() { auto fooFunc = &foo; static assert(!is(typeof(fooFunc) == function)); static assert( isFunctionPointer!(typeof(fooFunc))); static assert(!isDelegate!(typeof(fooFunc))); static assert( isSomeFunction!(typeof(fooFunc))); } static assert( is(typeof(Object.toString) == function)); static assert(!isFunctionPointer!(typeof(Object.toString))); static assert(!isDelegate!(typeof(Object.toString))); static assert( isSomeFunction!(typeof(Object.toString))); static assert(!is(typeof(&Object.toString) == function)); static assert( isFunctionPointer!(typeof(&Object.toString))); static assert(!isDelegate!(typeof(&Object.toString))); static assert( isSomeFunction!(typeof(&Object.toString)));
isSomeFunction for all of them is true , because all of them are either functions, or stateless function pointers, or delegates.
foo , bar , boz and Object.toString are all functions, so they are true for is(T == function) , but not for others.
fooFunc , bozFunc and &Object.toString are pointers to stateless functions, so they are true for isFunctionPointer!T , but not for the rest.
barDel is a delegate, so it is true for isDelegate!T , but not for the rest.
Hope this makes your work easier.