【发布时间】:2021-06-22 20:25:41
【问题描述】:
我有以下代码
using my_map_t = std::map<int, Object<double>>;
using my_map_iterator_t = my_map_t::iterator;
template <typename FWD, typename Func>
void inner(my_map_t& map, int key, FWD&& obj, Func emplacer) {
emplacer(map, key, std::forward<FWD>(obj));
}
my_map_t map;
template <typename FWD>
void outer(my_map_t& map, int key, FWD&& obj)
{
auto lambda = [](my_map_t& m, int k, FWD&& o) {
m.emplace(k, std::forward<FWD>(o));
};
inner(map, key, std::forward<FWD>(obj), lambda);
}
编译无痛。所以这意味着他自动推导出inner函数的模板参数。
但是,如果我引入一个函数指针我需要指定函数指针模板参数,否则编译器会抱怨
using my_map_t = std::map<int, Object<double>>;
using my_map_iterator_t = my_map_t::iterator;
template <typename FWD, typename Func>
void inner(my_map_t& map, int key, FWD&& obj, Func emplacer) {
emplacer(map, key, std::forward<FWD>(obj));
}
template <typename FWD, typename Func>
void(*fp)(my_map_t&, int, FWD&&, Func) = &inner;
my_map_t map;
template <typename FWD>
void outer(my_map_t& map, int key, FWD&& obj)
{
auto lambda = [](my_map_t& m, int k, FWD&& o) {
m.emplace(k, std::forward<FWD>(o));
};
(*fp<FWD, decltype(lambda)>)(map, key, std::forward<FWD>(obj), lambda);
}
为什么在函数指针的情况下,参数推导不再起作用? 我犯了什么错误吗?有没有办法获得更好的语法?
添加注释
我需要使用函数指针,因为我有一些与inner 签名相同的函数。让我们称他们为inner1、inner2 和inner3。它们被一些外部函数调用
void outer(...) {
if(...) {
inner1(...)
} else if (...) {
inner2(...)
} else {
inner3(...)
}
some_long_task(...)
}
现在在我的例子中,outer 函数被循环调用。 ifs 中的检查可能很耗时,并且它们独立于 outer 函数的参数。在执行some_long_task 时,我在想,利用一些cpu 并行性设置一个指向right 函数inner1、inner2 或inner3 的函数指针,这样,新的循环开始了,我不必浪费时间进行 if 检查。
【问题讨论】:
-
我有点困惑。不使用变量模板是否可以达到相同的结果(我发现它们是在 c++14 中引入的,我必须达到 C++11)?
-
为什么你需要
fp作为函数指针?为什么不是 lambda?从 C++14 开始,您可以将fp定义为[](my_map_t& map, int key, auto&& obj, auto func){ inner(map, key, std::forward<decltype(obj)>(obj), func); },或者在 C++11 中定义一个与此 lambda 相同的 functor。 -
我的意思是,我必须在函数内部定义函子(因为我使用 c++11)。有可能吗?
-
没有。类似于this question 和现在的其他人,你希望一些仿函数有一个模板接口,但是是一个单一的类型。这是不可能的,除非在未来的 C++ 中有虚拟函数模板。
-
您的“函数指针”的问题是您无法真正捕获额外的数据(您当前传递 lambda)。
std::function<void(my_map_t&, int)>可能是您想要的,而不是函数指针。
标签: c++ c++11 templates lambda type-deduction