我一定是误会了,因为我认为这两种情况是一样的:
#include <iostream>
void function() { std::cout << "Hi\n"; }
int main()
{
std::vector<void(*)()> funcPtrVec;
std::vector<void()> funcVec;
funcPtrVec.push_back(function); // Works
funcVec.push_back(function); // Works
auto lambdaFunc = []() { std::cout << "Hi\n"; };
funcPtrVec.push_back(lambdaFunc); // Works
funcVec.push_back(lambdaFunc); // Doesn't work
}
现在,在这两种情况下,我的编译器都说函数签名是相同的,void function()和void lambdaFunc()。我真的认为当lambda函数没有捕获任何东西时,它的行为就像一个自由函数,相同的签名似乎支持它。此外,我想我更加困惑,因为在下面的所有内容似乎都被视为同样的事情,就像腐烂到同样的事情一样:
void function() { std::cout << "Hi\n"; }
void funcTakingFunc(void()) {}
void funcTakingFuncPtr(void(*)()) {}
int main()
{
auto lambdaFunc = []() { std::cout << "Hi\n"; };
void(*funcPtr)() = lambdaFunc; // Works
funcTakingFuncPtr(lambdaFunc); // Works
funcTakingFuncPtr(funcPtr); // Works
funcTakingFunc(lambdaFunc); // Works
funcTakingFunc(funcPtr); // Works
// They all work
}
因此,我可以看到函数和函数指针之间的唯一区别是当作为vector的模板参数给出时。这显然意味着我不能很好地理解模板,但其原因是什么?因为我试过的例子中两者看起来真的相同。
答案 0 :(得分:2)
std::vector<void()>
是不允许的;该类型必须是对象类型,而函数类型不是对象类型。
向量需求规范的各个部分,我们可以确定它们被非对象类型所违反;最明显的是默认分配器。在[allocator.requirements] / 2中的表中,指定分配器的类型必须是对象类型。