Dlaczego nie ma std::protect
do użycia z std::bind
w C++ 11?Dlaczego nie ma std :: protect?
Boost.Bind zapewnia boost::protect
pomocnika, która otacza swój argument tak że boost::bind
nie rozpoznaje i ocenia je. std::[c]ref
byłaby wystarczająco dobrym zamiennikiem przez większość czasu, z tym wyjątkiem, że nie będzie przyjmować argumentu rvalue.
Dla konkretny przykład, rozważmy następujący sztuczną sytuację:
#include <type_traits>
#include <functional>
int add(int a, int b)
{ return a + b; }
struct invoke_with_42
{
template <typename FunObj>
auto operator()(FunObj&& fun_obj) const -> decltype((fun_obj(42)))
{ return fun_obj(42); }
};
int main()
{
//// Nested bind expression evaluated
//auto bind_expr =
// std::bind<int>(invoke_with_42{}
// , std::bind(&add, 1, std::placeholders::_1));
//// Compilation error, cref does not take rvalues
//auto bind_expr =
// std::bind<int>(invoke_with_42{}
// , std::cref(std::bind(&add, 1, std::placeholders::_1)));
//// Ok, inner_bind_expr must be kept alive
auto inner_bind_expr =
std::bind(&add, 1, std::placeholders::_1);
auto outer_bind_expr =
std::bind<int>(invoke_with_42{}, std::cref(inner_bind_expr));
//// Ok, with protect
//auto bind_expr =
// std::bind<int>(invoke_with_42{}
// , std::protect(std::bind(&add, 1, std::placeholders::_1)));
}
Czy to było proponowane? –
'cref' na' rvalue' prawdopodobnie byłby katastrofalny - życie tymczasowe nie utrzymałoby go tak długo, jak obiekt "bind", do którego jest przekazywany (lub cokolwiek). – Yakk
Możesz również "chronić", przypisując wynik 'bind' do' std :: function', ale dodaje on dodatkowe środowisko wykonawcze. – Potatoswatter