是否可以将函数引用保留到 unordered_map 或向量中?

Is it possible to reserve function reference into unordered_map or vector?

我正在制作一些回调系统,我想知道我是否可以保留对 unordered_map 的函数引用,以便我以后可以调用它。

float func_imp(float x)
{
    return x;
}
int main()
{
    using Tumap = unordered_map<int, float(&)(float)>;
    Tumap umap;
    umap.emplace(0, func_imp);
    (umap[0])(10.1); //a reference type cannot be value-initialized

    using Tvec = vector<float(&)(float)>;
    Tvec uvec; // pointer to reference is illegal
    //uvec.emplace_back(func_imp);
}

是否可以使用这种类型的容器来预留回调函数?如果不是,是否只能使用函数指针?

不管这是否是你应该做的事情(你问题下的评论已经涵盖了这一点),仍然值得按原样回答你的问题。

地图类型的[]运算符是名副其实的瑞士军刀。你可以用它做很多事情。

  • 您可以赋值。
  • 您可以查询该值。
  • 您可以查找一个值,即使它还不存在。

因此,使用该运算符会对地图中存储的任何类型提出一些要求。在这种特定情况下,您 运行 要求它必须是值可初始化的,而引用不能。

顺便说一句,这也适用于常规引用,而不仅仅是函数引用。

所以答案是:只要您不使用地图的任何需要引用来执行不允许的操作的功能,您就可以在地图中尽可能多地存储引用。

在这种情况下,您可以使用umap.at(0)(10.1);[]at() 之间的一大区别是,如果尚未设置密钥,at() 将抛出异常而不是创建值初始化值。

Is it possible to use this type of containers to ...

无论这句话如何继续:不,不可能使用这种类型的容器。具体可以参考没有标准容器的元素类型。引用类型不满足容器对其元素类型的要求(至少在使用标准分配器时不满足)。

if not, is it the only way to use function pointer?

不,函数指针不是唯一的方法,但它是 a 方法。

其他替代方案是函数对象,例如 std::function 等擦除函数包装器,或 std::reference_wrapper.

等引用包装器

i just thought there is no need to make dereference.

如果你的意思是语法上的,那么我有一个好消息可以让你的担忧变得无关紧要:没有必要通过指向函数的指针显式间接。间接寻址就像函数引用一样是隐式的。它们的调用语法是相同的示例:

float(&ref)(float) = func_imp;
float(*ptr)(float) = func_imp;
ref(42.);
ptr(42.);

因此,您不必担心。

如果您谈论的是必须在运行时通过指针间接访问以牺牲性能,那么我有一个坏消息让您的担忧无关紧要:引用也是一种间接访问形式,就像指针一样。它们(通常)不是优化。