gpt4 book ai didi

c++ - C++11 中带有可变参数模板的 bindParameter 函数

转载 作者:太空狗 更新时间:2023-10-29 21:06:09 25 4
gpt4 key购买 nike

我正在尝试编写一个简单的函数来转换 std::function<> 对象,同时绑定(bind)最后一个参数。这就是我所拥有的:

template<typename R, typename Bind, typename ...Args> std::function<R (Args...)> bindParameter (std::function<R (Args..., Bind)> f, Bind b)
{
return [f, b] (Args... args) -> R { return f (args..., b); };
}

这就是我想使用它的方式:

int blub (int a, int b)
{
return a * b;
}

// ...

int main ()
{
std::function<int (int, int)> f1 (blub);

// doesn't work
std::function<int (int)> f2 = bindParameter (f1, 21);

// works
std::function<int (int)> f3 = bindParameter<int, int, int> (f1, 21);

return f2 (2);
}

...所以在这个例子中,主函数应该返回 42。问题是,gcc (4.6) 似乎没有正确推断模板参数的类型,第一个版本产生以下错误:

test.cpp:35:58: error: no matching function for call to 'bindParameter(std::function<int(int, int)>&, int)'
test.cpp:35:58: note: candidate is:
test.cpp:21:82: note: template<class R, class Bind, class ... Args> std::function<R(Args ...)> bindParameter(std::function<R(Args ..., Bind)>, Bind)

但在我看来参数是显而易见的。或者这种类型推断是否未包含在标准中或尚未在 gcc 中实现?

最佳答案

您不能使用 std::function作为函数模板的推导参数。由于没有规则可以匹配int(*)(int, int),因此无法以这种方式进行演绎。至 std::function<int(int, int)> . (还要考虑对于 any std::function<Signature> 有一个构造函数接受 int(*)(int, int) ,即使在大多数情况下这会在实例化时导致错误。)

在一般情况下检测仿函数的签名是有问题的。即使是 KennyTM 的解决方案也有局限性:它检测单态仿函数和类似函数的东西的签名,但不适用于多态仿函数(例如重载 operator() )或具有代理调用函数的仿函数(即使在单态情况下)。

然而,由于 decltype,完全可以避免检测签名的问题。 (或等同于 std::result_of ),我建议这样做。因此,KennyTM 答案的一个变体:

template<typename Functor, typename Bound>
struct bind_last_type {
Functor functor;
Bound bound;

template<typename... Args>
auto operator()(Args&&... args)
-> typename std::result_of<Functor&(Args..., Bound)>::type
// equivalent:
// -> decltype( functor(std::forward<Args>(args)..., std::move(bound)) )
{ return functor(std::forward<Args>(args)..., std::move(bound)); }
};

template<typename Functor, typename Bound>
bind_last_type<
typename std::decay<Functor>::type
, typename std::decay<Bound>::type
>
bind_last(Functor&& functor, Bound&& bound)
{ return { std::forward<Functor>(functor), std::forward<Bound>(bound) }; }

关于c++ - C++11 中带有可变参数模板的 bindParameter 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8167374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com