2016-01-19 7 views
6

のは、次のコードを考えてみましょう:のstd ::バインドと右辺値参照

class Widget{ 
}; 

int main(){ 
Widget w; 
auto lambda = bind([](Widget&& ref){ return; }, std::move(w)); 

return 0; 
} 

、それは誤り

no match for call to ‘(std::_Bind<main()::<lambda(Widget&&)>(Widget)>)()’ 
    lambda(); 

をトリガし、私の質問がある:エラーが登場しているのはなぜ?結局、私は右辺値参照に明示的なキャストを行う - 私はstd::move(w)を意味し、私は右辺値参照で引数を取る - 私はWidget&& refを意味します。

アップは何ですか?

class Widget{ 
}; 

int main(){ 
Widget w; 
auto lambda = bind([](Widget& ref){ return; }, std::move(w)); 

return 0; 
} 

答えて

7

あなたはstd::bindを模式的に何をするか書き留めた場合にそれが明確になるかもしれません:私はより多くを心配するもの

また、以下のコードが動作します、。

// C++14, you'll have to write a lot of boilerplate code for C++11 
template <typename FuncT, typename ArgT> 
auto 
bind(FuncT&& func, ArgT&& arg) 
{ 
    return 
    [ 
     f = std::forward<FuncT>(func), 
     a = std::forward<ArgT>(arg) 
    ]() mutable { return f(a); }; // NB: a is an lvalue here 
} 

あなたはstd::bindはあなたに複数回与える関数オブジェクトを呼び出すことができますので、それは「使い切る」ことができない、それは左辺値参照として渡されますので、捕獲引数。あなたはbind自体右辺値渡したという事実だけでaが初期化されたラインで作られた何のコピーが存在しないことを意味します。

あなたは上に示した概略bindであなたの例をコンパイルしようとした場合、また、あなたのコンパイラからより有用なエラーメッセージが表示されます。それはあなたがこのようにそれを記述する必要が動作するように

main.cxx: In instantiation of ‘bind(FuncT&&, ArgT&&)::<lambda()> mutable [with FuncT = main()::<lambda(Widget&&)>; ArgT = Widget]’: 
main.cxx:10:33: required from ‘struct bind(FuncT&&, ArgT&&) [with FuncT = main()::<lambda(Widget&&)>; ArgT = Widget]::<lambda()>’ 
main.cxx:11:31: required from ‘auto bind(FuncT&&, ArgT&&) [with FuncT = main()::<lambda(Widget&&)>; ArgT = Widget]’ 
main.cxx:18:59: required from here 
main.cxx:11:26: error: no match for call to ‘(main()::<lambda(Widget&&)>) (Widget&)’ 
    ]() mutable { return f(a); }; // NB: a is an lvalue here 
         ^
main.cxx:11:26: note: candidate: void (*)(Widget&&) <conversion> 
main.cxx:11:26: note: conversion of argument 2 would be ill-formed: 
main.cxx:11:26: error: cannot bind ‘Widget’ lvalue to ‘Widget&&’ 
main.cxx:18:33: note: candidate: main()::<lambda(Widget&&)> <near match> 
    auto lambda = bind([](Widget&&){ return; }, std::move(w)); 
           ^
main.cxx:18:33: note: conversion of argument 1 would be ill-formed: 
main.cxx:11:26: error: cannot bind ‘Widget’ lvalue to ‘Widget&&’ 
    ]() mutable { return f(a); }; // NB: a is an lvalue here 
1

#include <functional> 
#include <iostream> 

class Widget{}; 

int main() 
{ 
    Widget a; 
    auto lf = [](Widget&& par){ }; 

    auto f = std::bind 
    (
     lf, 
     std::bind 
     (
      std::move<Widget&>, a 
     ) 
    ); 
    f(); 
    return 0; 
} 

私のコンパイラはあなたの例では動作しませんgcc version 4.9.2 20141101 (Red Hat 4.9.2-1) (GCC)

+1

です。 f()を呼び出してみてください。 – Gilgamesz

+0

この例がうまくいかないことは、どのようにしてわかりましたか?コンパイラで正常にコンパイルしました。どのようなコンパイラを使用しますか? – zaratustra

+0

http://ideone.com/tl8tc3 – Gilgamesz

関連する問題