问题描述
我不知道如何可以完成以下操作
I wonder how the following can be done
void f(string &&s) {
std::string i(move(s));
/* other stuff */
}
int main() {
std::string s;
bind(f, s)(); // Error.
bind(f, move(s))(); // Error.
bind(f, ref(s))(); // Error.
}
如何传递右值引用并将其存储为右值引用包装)在调用包装器?我知道我可以手动写一个类如 std :: reference_wrapper<>
有一个转换函数 T&&
,但我宁愿想避免和使用标准技术。
How can I pass an rvalue reference and store it as an rvalue reference (possibly wrapped) in the call wrapper? I know I can manually write up a class like std::reference_wrapper<>
that has a conversion function to T&&
, but I would rather want to avoid that and use Standard technology.
我实现了它像AProgrammer建议:
I implemented it like AProgrammer recommends:
template<typename T> struct adv {
T t;
explicit adv(T &&t):t(forward<T>(t)) {}
template<typename ...U> T &&operator()(U &&...) {
return forward<T>(t);
}
};
template<typename T> adv<T> make_adv(T &&t) {
return adv<T>{forward<T>(t)};
}
namespace std {
template<typename T>
struct is_bind_expression< adv<T> > : std::true_type {};
}
现在我可以说
void f(string &&s) {
std::string i(move(s));
/* other stuff */
}
int main() {
std::string s;
bind(f, make_adv(move(s)))(); // Works!
}
如果我们将一个左值传递给 make_adv
,它会将它转发为一个引用输入参数的左值,因此在这种情况下,它可以用作 std :: ref
的替换。
If we pass an lvalue to make_adv
, it will forward it as an lvalue referring to the input argument, so it can be used as a replacement for std::ref
, in this case.
推荐答案
我的承诺。
20.8.10.1.2 / 10 in N3225
20.8.10.1.2/10 in N3225
- 如果TiD是reference_wrapper,则参数是tid.get(),其类型Vi是T& ;;
- 如果is_bind_expression :: value的值为true,参数是tid(std :: forward(uj)...)
,其类型Vi是result_of :: type; - 如果is_placeholder: :值不为零,参数为std :: forward(uj)
,其类型Vi为Uj&& ;; - 否则,值为tid, Vi是TiD cv&。
- if TiD is reference_wrapper, the argument is tid.get() and its type Vi is T&;
- if the value of is_bind_expression::value is true, the argument is tid(std::forward(uj)...) and its type Vi is result_of::type;
- if the value j of is_placeholder::value is not zero, the argument is std::forward(uj) and its type Vi is Uj&&;
- otherwise, the value is tid and its type Vi is TiD cv &.
因此,有一个右值引用的唯一可能是 is_bind_expression< TiD> :: value
true或 is_placeholder< TiD> :: value
不为零。第二种可能性是你不想要的,并实现想要的结果与第一种意味着如果我们限制到标准提供的类型,我们试图解决的问题是解决的。所以,唯一的可能性是提供自己的包装和 is_bind_expression< TiD>
(由20.8.10.1.1 / 1允许)见一个。
So the only possibility to have a rvalue reference is to have is_bind_expression<TiD>::value
true or is_placeholder<TiD>::value
not zero. The second possibility has implications you don't want and achieving the wanted result with the first would imply that the problem we are trying to solve is solved if we restrict to the standard provided types. So, the only possibility would be to provide your own wrapper and a specialisation for is_bind_expression<TiD>
(that is allowed by 20.8.10.1.1/1) as I don't see one.
这篇关于是否有reference_wrapper<>用于右值引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!