是否可以将函数引用保留到 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.);
因此,您不必担心。
如果您谈论的是必须在运行时通过指针间接访问以牺牲性能,那么我有一个坏消息让您的担忧无关紧要:引用也是一种间接访问形式,就像指针一样。它们(通常)不是优化。
我正在制作一些回调系统,我想知道我是否可以保留对 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.);
因此,您不必担心。
如果您谈论的是必须在运行时通过指针间接访问以牺牲性能,那么我有一个坏消息让您的担忧无关紧要:引用也是一种间接访问形式,就像指针一样。它们(通常)不是优化。