且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用C ++中的显式原型进行返回类型推导

更新时间:2023-02-12 23:39:44

这是因为函数表和重载函数在C ++中的工作方式。

It's because of how the function tables and overloaded functions work in C++.

当编译器读取您的 std :: string some_function()时; 会在二进制文件中创建一个供其引用的位置,并说出是否曾经有人将此函数跳转到此位置。

When the compiler reads your std::string some_function(); it creates a spot for it to reference in the binary and says if "this function is ever called jump to this spot".

因此我们有一个看起来像这样的vtable ...

So we have a vtable that looks like this...

(Address offset)  (Symbol)
0x????????       std::string somefunction();

现在它进入您的 auto some_function(){...} 。通常,它首先会在函数表中查找 auto somefunction(); 是否存在于表中或表的某些变体中,但是编译器会注意到这是一个实现,并且它具有auto关键字,因此为了减少熵,它在函数表中写入 * blank * some_function(); 并绑定以解决返回类型。

Now it gets to your auto some_function() {...}. Normally it would first look in the function table to see if auto somefunction(); exists in the table or some variation there of, but the compiler notices that this is a implementation and it has the auto keyword so to reduce the entropy it writes *blank* some_function(); to the function table and ties to solve the return type.

现在函数表看起来像这样...

Now the Function table looks like this...

(Address offset)  (Symbol)
0x????????       std::string somefunction();
0x????????       ????? somefunction();

因此,当找到返回类型(在这种情况下为 std :: string 。现在,编译器知道返回类型是什么,因此可以转到函数表并更改 auto somefunction(); 还要 std :: string somefunction() ;

So it chugs along compiling code into binary when it finds out the return type which in this case is std::string. The compiler now knows what the return type is so it goes to the function table and changes auto somefunction(); too std::string somefunction();.

现在,函数表如下所示……

Now the Function table looks like this...

(Address offset)  (Symbol)
0x????????       std::string somefunction();
0x????????       std::string somefunction();

现在,编译器返回并继续编译该函数。完成后,返回并完成vtable,只发现其中两次存在相同的符号。

Now the compiler goes back and continues to compile the function. Once it's done it goes back and finishes up the vtable only to find the same symbol is in there twice. It's now ambiguous to which symbol we are referring too.

那么这是什么原因呢?

不是100%可以确定,但是在对代码进行充分精简以允许创建推论类型之前,就已经创建了vtable。因此,编译器在该阶段必须使用的唯一选择就是假设它是一个新符号。这只是我整天都在看符号表并编写自己的C ++ 11编译器的事情。

Not 100% sure but vtables are made long before your code is worked down enough to allow for the deduction type to be made. So the only option the compiler has to work with at that stage in time is to just assume it's a new symbol. It's just something I've noticed looking at symbol tables all day and writing my own C++11 compiler.

但是我绝不能说其他很多编译器关于优化和其他步骤的介绍,我只是简单地工作,但这就是我对标准的理解。

I however can in no way speak for other compilers where lots of optimizations and other steps are introduced, I just work with the bare bones, however that is my understanding of the standard.

该类型的最后一件事是完全任意的。扣除时他们是否不匹配甚至无关紧要。从来没有那么远。问题出在表中有两个相同的符号,并且您不能在返回类型上重载。

One last thing the type is completely arbitrary. It doesn't even matter if they don't match at the time of deduction. It never get's that far. The problem arises that there are two of the same symbols in the table, and you can't overload on return types.