无法隐式初始化std :: function [英] Cannot inititialize std::function implicitly

查看:296
本文介绍了无法隐式初始化std :: function的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将此函子编写为执行操作(&& ):

I've written this functor to perform an and operation (&&):

// unary functor; performs '&&'
template <typename T>
struct AND
{
    function<bool (const T&)> x;
    function<bool (const T&)> y;

    AND(function<bool (const T&)> xx, function<bool (const T&)> yy) 
             : x(xx), y(yy) {}
    bool operator() ( const T &arg ) { return x(arg) && y(arg); }
};

// helper
template <typename T>
AND<T> And(function<bool (const T&)> xx, function<bool (const T&)> yy)
{
    return AND<T>(xx,yy);
}

注意它是构造函数参数类型: function< bool(const T&)>

Note it's constructor argument types: function<bool (const T&)>.

现在,我正在尝试以各种方式实例化它(在 big_odd_exists()):

Now, I am trying to instantiate it in various ways (inside big_odd_exists()):

int is_odd(int n) { return n%2; }
int is_big(int n) { return n>5; }


bool big_odd_exists( vector<int>::iterator first, vector<int>::iterator last ) 
{
    function<bool (const int &)> fun1 = is_odd;
    function<bool (const int &)> fun2 = is_big;

    return any_of( first, last, And( fun1, fun2 ) );  // instantiating an And object
}

int main()
{
    std::vector<int> n = {1, 3, 5, 7, 9, 10, 11};

    cout << "exists : " << big_odd_exists( n.begin(), n.end() ) << endl;
}

令我惊讶的是, std :: functions 将会编译。

To my surprise, none of the implicit instantiations of the std::functions would compile.

以下是我尝试过的情况(g ++-4.8):

Here are the cases I've tried (g++-4.8):

function<bool (const int &)> fun1 = is_odd;
function<bool (const int &)> fun2 = is_big;

return any_of( first, last, And( fun1, fun2 ) );



这不会进行编译(隐式实例化 std :: function 的一个临时对象):



This does not compile (implicit instantiation of a temporary std::function object):

return any_of( first, last, And( is_odd, is_big ) );   // error: no matching function for call to ‘And(int (&)(int), int (&)(int))’



这将进行编译(<< c $ c> std :: function 对象的显式实例化):



This compiles (explicit instantiation of a std::function object):

function<bool (const int &)> fun1 = bind(is_odd,_1);
function<bool (const int &)> fun2 = bind(is_big,_1);

return any_of( first, last, And(fun1, fun2) );



这不会进行编译(隐式实例化 std :: function 的一个临时对象):



This does not compile (implicit instantiation of a temporary std::function object):

return any_of( first, last, And(bind(is_odd,_1), bind(is_big,_1)) );  // error: no matching function for call to ‘And(std::_Bind_helper<false, int (&)(int), const std::_Placeholder<1>&>::type, std::_Bind_helper<false, int (&)(int), const std::_Placeholder<1>&>::type)’

据我了解, std :: functions 确实具有显式构造函数。
那么,为什么我不能使用 nicer来读取版本的电话?

As far as I understand, the std::functions do not have explicit constructors. So, why can't I use the nicer to read versions of the calls?

我拥有所有测试用例:
http://coliru.stacked-crooked.com/a/ded6cad4cab07541

I have all the test cases in: http://coliru.stacked-crooked.com/a/ded6cad4cab07541

推荐答案

我建议不要滥用 std :: function 并采取正常措施而是通用参数。将 std :: function 视为具有特定签名的可调用对象的类型擦除的容器(请参见 https://stackoverflow.com/a/11629125/46642 了解更多信息)。

I suggest not abusing std::function and taking normal generic parameters instead. Treat std::function as a type-erased container for callable objects of a particular signature (see https://stackoverflow.com/a/11629125/46642 for more details).

// unary functor; performs '&&'
template <typename X, typename Y>
struct AND
{
    X x;
    Y y;

    template <typename XX, typename YY>
    AND(XX&& xx, YY&& yy) 
             : x(std::forward<XX>(xx)), y(std::forward<YY>(yy)) {}

    template <typename T>
    auto operator() ( const T &arg ) -> decltype(x(arg) && y(arg))
    { return x(arg) && y(arg); }
};

template <typename T>
using Decay = typename std::decay<X>::type;

// helper
template <typename X, typename Y>
AND<Decay<X>, Decay<Y>> And(X&& xx, Y&& yy)
{
    return AND<Decay<X>, Decay<Y>>(std::forward<X>(xx), std::forward<Y>(yy));
}

这篇关于无法隐式初始化std :: function的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆