標籤:

C++ 如何寫一個函數,使得它的返回值是指向該函數自身的指針?

比如我想寫個Foo()函數,使得它的返回值為Foo,那麼這個函數怎麼定義?返回值的類型應該怎麼寫?


問題含糊不清,我只能理解為題主遇到了函數指針類型的定義不能遞歸地問題,這通常都可以用一個新的類型來解決(typedef和using不創建新的類型,不能用),VC++ 2015編譯通過

class Shit
{
public:
struct Bitch
{
Bitch(Shit::*pointer)();
};

Bitch GetShit()
{
return{ Shit::GetShit };
}
};

用法:

Shit shit;
auto pointer = (shit.*(shit.GetShit().pointer))().pointer;
assert(pointer == Shit::GetShit);


如果僅僅從類型的角度考慮的話,這超出了類型系統的能力範圍,題主提到的這種遞歸類型叫做 equirecursive types,說白了就是實現一個具有類似下面類型的函數:

type Equirecursive = Int -&> Int -&> Equirecursive

而且不僅 C++ 的類型系統不支持,Haskell 和 OCaml 也不支持。因為這會增加類型檢查系統的負擔,而且這樣的特性基本沒人用。經評論區的朋友提醒,Scala 和 Haxe 是支持的,具體見這篇文章。

但是別忘了我們可以重載 operator() 啊,你只要返回一個可調用的對象就行了:

class Function {
public:
Function operator() (int a, int b) const {
// do whatever you want
return Function { }; // returns a new function instance
}
};

int main() {
Function func { };
func(1, 2)(3, 4)(5, 6);
return 0;
}


這樣不行嗎?


刨除PLT的問題的話,這問題很好解決的。


用內聯彙編,在內存里往前面找到函數入口時彈棧的操作,將其虛地址返回。

不過這樣不能跨平台


指針不行,因為需要無限遞歸返回值類型

要用函數對象


簡單起見要不用functor?

重載括弧,返回this?


加個容器就可以了。

struct Wapper

{

Wapper (*pfn)();

};

Wapper getself();

Wapper wp;

Wapper getself()

{

wp.pfn = getself;

return wp;

}


用typedef是一種比較好的方式,可讀性較高,使用起來也比較方便。比如:

typedef void (*func)(int, int); // 定義了一個函數指針的類型別名

func現在就代表了一個返回值類型為void,帶有兩個int形參的函數的指針。


有人可能看這個類型轉換不順眼,但這是最簡潔的辦法。


我來一個彙編的 哈哈

PVOID _declspec(naked) Foo()
{
__asm
{
call $+5
pop eax
sub eax, 5
ret
}
}


推薦閱讀:

斷言、異常和返回值的選擇問題?
Qt 為什麼在桌面應用(Windows 平台)中不流行呢?
當面試官問我C++ 11新特性的時候,應該怎樣回答?
既然c++模板元編程是圖靈完全的,那麼刷leetcode的時候如果都用模板元編程,能不能全刷成0ms?
如何使用C++實現一個and函數?

TAG:C編程語言 | C | CC |