gpt4 book ai didi

c++ - 为什么没有 std::protect?

转载 作者:太空宇宙 更新时间:2023-11-04 13:48:51 25 4
gpt4 key购买 nike

为什么 C++11 中没有 std::protectstd::bind 一起使用?

Boost.Bind 提供了一个 boost::protect 帮助器来包装它的参数,这样 boost::bind 就不会识别和评估它. std::[c]ref 在大多数情况下是一个足够好的替代品,除了它不会将 rvalue 作为参数。

举个具体的例子,考虑下面的人工情况:

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

最佳答案

嗯,我不知道为什么它没有实现。也许它没有被提议,或者可能存在一些微妙的问题。

也就是说,我认为您可以很容易地编写它

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

protect 的两个版本使得非绑定(bind)表达式不被包装(它们只是通过)。其他一切都通过移动/复制传递给 protect_wrapper,它只是从类型继承。这允许类型的函数通过,或将其转换为类型。

但是它会进行复制/移动,因此可以安全地与 rvals 一起使用。由于它只保护 bind_expressions 类型,因此它最大限度地减少了必须发生的复制量。

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;

}

关于c++ - 为什么没有 std::protect?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24404691/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com