简短的回答:
is(T == function)
是否T
是函数
isFunctionPointer!T
是否T
是函数指针(而不是委托)
isDelegate!T
是否T
为代表
isSomeFunction!T
T
是函数、函数指针 还是委托
长答案:
函数就是函数。
auto func(int val) {...}
它是一段代码,您可以使用该名称调用该名称。你给它参数,它做任何事情,它返回一个结果。你可以调用它,但你不能传递它。你需要一个函数指针。
函数指针是指向函数的指针。因此,就像int
is anint
和int*
是指向 an 的指针int
,而int
不是指向 的指针一样,函数也不是函数指针。int
如果你想要一个函数指针,你需要一个指向函数的指针。语法与它的语法不同int
,但它是相同的概念。
委托是具有状态的函数指针。例如,在
int foo(int value)
{
int bar()
{
return value + 5;
}
auto barDel = &bar;
return barDel();
}
void main()
{
auto fooFunc = &foo;
}
foo
是一个函数,bar
是一个可以访问其外部范围的嵌套函数,并且barDel
是一个委托,因为它是一个具有状态(bar
可以访问的外部状态)的函数指针。如果你传递barDel
给另一个函数(或返回它),你会得到一个闭包(除非传递给它的函数接受委托scope
,在这种情况下,该函数保证委托不会逃脱其范围),因为该状态需要放在堆上,以便它继续存在,即使它的状态来自的函数调用在它被调用时已经完成。funcFoo
另一方面,它是一个函数指针,因为foo
它没有任何外部状态。如果bar
是static
,那么barDel
也将是一个函数指针而不是一个委托,因为bar
将不再有权访问它所在的函数(尽管它的主体必须更改,因为它不再有权访问value
)。
现在,至于你的例子。Object.toString
是 的成员函数Object
。所以,它是一个函数。它没有与之关联的状态。函数永远不会。它当前的签名是
string toString();
但是因为它是 的成员函数Object
,所以它的签名实际上类似于
string toString(Object this);
this
toString
作为参数传递给。它不是与 关联的状态toString
。所以,&Object.toString
不是代表。它只是一个函数指针。并且Object.toString
不是函数指针,所以即使&Object.toString
是委托,static assert(isDelegate!(typeof(Object.toString)))
仍然会失败,因为要成为委托,它必须是函数指针,但事实并非如此。这是一个功能。
现在,不幸的是,typeof(&Object.toString)
被认为是string function()
而不是string function(Object)
,因此使用它来调用toString
实际Object
需要一些工作。可以做到,但我现在不记得是怎么做到的(而且 IIRC 有点难看)。但无论如何它都不会是委托,因为没有与之关联的状态。
如果您想要一个可以传递Object
给并让它调用成员函数的函数,那么您可以执行类似的操作
auto obj = getObjectFromSomewhere();
auto func = function(Object obj){return obj.toString();};
auto result = func(obj);
如果您想将一个对象与一个成员函数相关联,并且能够在该对象上调用该成员函数而无需传递该对象,那么您只需将其包装在一个委托中:
auto obj = getObjectFromSomewhere();
auto del = delegate(){return obj.toString();};
auto result = del();
这段代码应该总结并很好地说明事情:
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
适用true
于所有这些,因为它们要么是函数,要么是没有状态的函数指针,要么是委托。
foo
, bar
, boz
, 和Object.toString
都是函数,所以它们true
适用于其他函数,is(T == function)
而不适用于其他函数。
fooFunc
, bozFunc
, 和是没有 state&Object.toString
的函数指针,所以它们是用于但不是用于其他的。true
isFunctionPointer!T
barDel
是一个代表,所以它是true
给其他人的,isDelegate!T
但不是给其他人的。
希望这可以为您解决问题。