无法隐式初始化std :: function

Gri*_*ngo 3 c++ stl c++11

我写了这个仿函数来执行操作(&&):

// 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);
}
Run Code Online (Sandbox Code Playgroud)

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

现在,我试图以各种方式(内部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;
}
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,没有任何隐式实例化std::functions会编译.

以下是我尝试过的案例(g ++ - 4.8):

这编译(对象的显式实例化std::function):

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

return any_of( first, last, And( fun1, fun2 ) );
Run Code Online (Sandbox Code Playgroud)

这并没有编译(隐式的临时的实例化std::function对象):

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

这编译(对象的显式实例化std::function):

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) );
Run Code Online (Sandbox Code Playgroud)

这并没有编译(隐式的临时的实例化std::function对象):

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)’
Run Code Online (Sandbox Code Playgroud)

据我明白了,std::functions没有显式的构造.那么,为什么我不能使用更好的阅读版本的电话?

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

Rei*_*ica 6

问题是T在这种情况下无法推断.让我们从编译器的角度来看待它:

template <typename T>
AND<T> And(function<bool (const T&)> xx, function<bool (const T&)> yy)

// Later, invoked as:
And( is_odd, is_big )
Run Code Online (Sandbox Code Playgroud)

"嗯,不T上调用指定的,我将不得不推断出这一点.有什么说法?is_odd,这是衰减到输入int (*)(int).现在,我会以实例std::function<bool (const T&)>所有可能的T值,看看哪个/如果可以用任何它从类型来看,int (*)(int)嗯,其中有很多.不会这样做."

如果您明确指定Ttempalte参数,它将起作用:

return any_of( first, last, And<int>( is_odd, is_big ) );
Run Code Online (Sandbox Code Playgroud)

实例


请注意,即使您更改is_odd并完全is_big匹配function签名(返回bool和拍摄const int&),这也会成立.这是演绎的问题.

  • 如果编译器实例化所有模板,它甚至不会有帮助,因为结果仍然是不明确的.使用额外的重载`template <typename R,typename A> AND <A>和(R(*xx)(A),R(*yy)(A))`你甚至不需要显式的模板参数.真正的问题是过早地丢弃参数的类型. (3认同)