为什么这些函数签名的处理方式不同?

Why aren't these function signatures treated the same?

本文关键字:处理 方式不 函数 为什么      更新时间:2023-10-16

我必须误解某些东西,因为我认为两种情况是相同的:

#include <iostream>
    void function() { std::cout << "Hin"; }
    int main()
    {
        std::vector<void(*)()> funcPtrVec;
        std::vector<void()> funcVec;
        funcPtrVec.push_back(function); // Works 
        funcVec.push_back(function);    // Works
        auto lambdaFunc = []() { std::cout << "Hin"; };
        funcPtrVec.push_back(lambdaFunc);   // Works
        funcVec.push_back(lambdaFunc);      // Doesn't work
    }

现在,在这两种情况下,我的编译器都说函数签名是相同的,void函数()和void lambdafunc()。我真的认为,当lambda函数没有捕获任何表现就像自由功能一样,同一签名似乎支持。另外,我想我更加困惑,因为在下面的情况下,所有这些都被对待一样,就好像腐烂了同一件事:

void function() { std::cout << "Hin"; }
void funcTakingFunc(void()) {}
void funcTakingFuncPtr(void(*)()) {}
int main()
{
    auto lambdaFunc = []() { std::cout << "Hin"; };
    void(*funcPtr)() = lambdaFunc;  // Works
    funcTakingFuncPtr(lambdaFunc);  // Works
    funcTakingFuncPtr(funcPtr);     // Works
    funcTakingFunc(lambdaFunc);     // Works
    funcTakingFunc(funcPtr);        // Works
    // They all work
}

因此,据我所知,当函数和函数指针之间的唯一区别是作为模板参数与向量的模板参数时。这显然意味着我不太了解模板,但是这样做的原因是什么?因为我尝试过的示例确实看起来确实一样。

std::vector<void()>不允许;该类型必须是对象类型,函数类型不是对象类型。

矢量要求的规范中有各种各样的部分,我们可以识别为非对象类型的侵犯;最明显的是默认分配器。在[salocator.requirement]/2的表中,指定分配器的类型必须是对象类型。