I’m really confused at the documentation of isSomeFunction, as well as at the following code:
static assert(!isFunctionPointer!(typeof(Object.toString))); // makes sense
static assert(!isDelegate!(typeof(Object.toString))); // what??
static assert( isSomeFunction!(typeof(Object.toString))); // what??
Could someone please explain the difference between a “function” and a “function pointer” to me?
Short Answer:
is(T == function)WhetherTis a functionisFunctionPointer!TWhetherTis a function pointer (and not a delegate)isDelegate!TWhetherTis a delegateisSomeFunction!TWhetherTis a function, a function pointer, or a delegateLong Answer:
A function is, well, a function.
It’s a chunk of code with a name that you can call using that name. You give it arguments, it does whatever it does, and it returns a result. You can call it, but you can’t pass it around. You need a function pointer for that.
A function pointer is a pointer to a function. So just like
intis anintandint*is a pointer to anint, andintis not a pointer toint, a function isn’t a function pointer. If you want a function pointer, you need a pointer to a function. The syntax is different from how it is withint, but it’s the same concept.A delegate is a function pointer with state. So for instance, in
foois a function,baris a nested function which has access to its outer scope, andbarDelis a delegate, because it’s a function pointer with state (the outer state thatbarhas access to). If you passbarDelto another function (or return it), you’ll get a closure (unless the function it’s passed to takes the delegate byscope, in which case that function guarantees that the delegate will not escape its scope), because that state needs to be put on the heap so that it continues to exist even if the function call that its state comes from has completed when it’s called.funcFoo, on the other hand, is a function pointer, becausefoodoesn’t have any outer state. Ifbarwerestatic, thenbarDelwould also be a function pointer rather than a delegate, becausebarwould no longer have access to the function that it’s in (though its body would then have to be changed, since it would no longer have access tovalue).Now, as to your example.
Object.toStringis a member function ofObject. So, it’s a function. It has no state associated with it. Functions never do. Its current signature isBut because it’s a member function of
Object, its signature is really something likethisis passed totoStringas an argument. It’s not state associated withtoString. So,&Object.toStringis not a delegate. It’s just a function pointer. AndObject.toStringisn’t a function pointer, so even if&Object.toStringwere a delegate,static assert(isDelegate!(typeof(Object.toString)))would still fail, because in order to be a delegate, it must be a function pointer, which it’s not. It’s a function.Now, unfortunately,
typeof(&Object.toString)is considered to bestring function()rather thanstring function(Object), so using it to calltoStringwith an actualObjecttakes a bit of work. It can be done, but I don’t remember how at the moment (and it’s a bit ugly IIRC). But it wouldn’t be a delegate regardless, because there’s no state associated with it.If you want a function that you can pass an
Objectto and have it call a member function, then you could do something likeIf you want to associate an object with a member function and be able to call that member function on that object without having to pass the object around, then you just wrap it in a delegate:
This bit of code should sum things up and illustrate things fairly well:
isSomeFunctionistruefor all of them, because they’re all either functions, function pointers without state, or delegates.foo,bar,boz, andObject.toStringare all functions, so they’retrueforis(T == function)but not for the others.fooFunc,bozFunc, and&Object.toStringare function pointers without state, so they’retrueforisFunctionPointer!Tbut not for the others.barDelis a delegate, so it’strueforisDelegate!Tbut not for the others.Hopefully, that clears things up for you.