thesis page letterpaper documentclass classes book begin appendix c++ c++11

c++ - page - ¿Por qué no hay std:: protect?



latex letter page size (1)

Bueno, no sé por qué no se implementó. Tal vez no fue propuesto, o tal vez hubo algunas trampas sutiles.

Dicho esto, creo que puedes escribirlo bastante fácilmente

template<typename T> struct protect_wrapper : T { protect_wrapper(const T& t) : T(t) { } protect_wrapper(T&& t) : T(std::move(t)) { } }; template<typename T> typename std::enable_if< !std::is_bind_expression< typename std::decay<T>::type >::value, T&& >::type protect(T&& t) { return std::forward<T>(t); } template<typename T> typename std::enable_if< std::is_bind_expression< typename std::decay<T>::type >::value, protect_wrapper<typename std::decay<T>::type > >::type protect(T&& t) { return protect_wrapper<typename std::decay<T>::type >(std::forward<T>(t)); }

Las dos versiones de protect son para que las expresiones no vinculantes no se envuelvan (solo pasan). Todo lo demás se pasa por mover / copiar a protect_wrapper , que simplemente se hereda del tipo. Esto permite que las funciones del tipo pasen a través o que se conviertan al tipo.

Sin embargo, realiza una copia / movimiento, por lo que puede usarse de forma segura con rvals. Y como solo protege los tipos que son bind_expressions, minimiza la cantidad de copias que se deben producir.

int main() { //// Ok, with protect auto bind_expr = std::bind<int>(invoke_with_42{} , protect(std::bind(&add, 1, std::placeholders::_1))); std:: cout << bind_expr() << std::endl; return 0; }

¿Por qué no hay std::protect para usar junto con std::bind en C ++ 11 ?

Boost.Bind proporciona un ayudante boost::protect que envuelve su argumento para que boost::bind no lo reconozca ni lo evalúe. std::[c]ref sería un buen reemplazo la mayoría de las veces, excepto que no tomará un valor de r como valor de argumento.

Para un ejemplo concreto, considere la siguiente situación artificial:

#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))); }