gpt4 book ai didi

function - “函数”与“函数指针”的区别是什么?

转载 作者:行者123 更新时间:2023-12-04 05:28:03 24 4
gpt4 key购买 nike

我对the documentation of isSomeFunction以及以下代码感到困惑:

static assert(!isFunctionPointer!(typeof(Object.toString)));  // makes sense
static assert(!isDelegate!(typeof(Object.toString))); // what??
static assert( isSomeFunction!(typeof(Object.toString))); // what??


有人可以向我解释“函数”和“函数指针”之间的区别吗?

最佳答案

简短答案:

is(T == function) T是否为函数
isFunctionPointer!T T是否为函数指针(而不是委托)
isDelegate!T T是否是代理
isSomeFunction!T T是函数,函数指针还是委托

长答案:
函数就是函数。

auto func(int val) {...}

它是一个带有名称的代码块,您可以使用该名称来调用它。您给它提供参数,它会做任何事情,然后返回结果。您可以调用它,但是不能传递它。为此,您需要一个函数指针。
函数指针是指向函数的指针。因此,就像 intintint*是指向 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没有任何外部状态。如果 barstatic,则 barDel还将是函数指针而不是委托,因为 bar将不再有权访问其所在的函数(尽管随后必须更改其主体,因为它将不再有权访问 value)。
现在,以您的示例为例。 Object.toStringObject的成员函数。因此,这是一个功能。它没有与之关联的状态。函数永远做不到。当前签名是
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,因为它们都是函数,无状态的函数指针或委托。
foobarbozObject.toString都是函数,因此它们对 true来说是 is(T == function),对于其他功能则不是。
fooFuncbozFunc&Object.toString是没有状态的函数指针,因此它们是 trueisFunctionPointer!T而不是其他的。
barDel是委托,因此对于 trueisDelegate!T,对于其他人则不是。
希望这可以为您清除一切。

关于function - “函数”与“函数指针”的区别是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11067972/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com