两个超载的STD ::前进工作如何
How do two overloaded std::forward work?
我在std库中找到了以下STD :: forward的实现:
// TEMPLATE FUNCTION forward
template<class _Ty> inline
constexpr _Ty&& forward(
typename remove_reference<_Ty>::type& _Arg) _NOEXCEPT
{ // forward an lvalue as either an lvalue or an rvalue
return (static_cast<_Ty&&>(_Arg));
}
template<class _Ty> inline
constexpr _Ty&& forward(
typename remove_reference<_Ty>::type&& _Arg) _NOEXCEPT
{ // forward an rvalue as an rvalue
static_assert(!is_lvalue_reference<_Ty>::value, "bad forward call");
return (static_cast<_Ty&&>(_Arg));
}
第一个功能显然有效,但是第二个功能我找不到有用的示例。如果我尝试做这样的事情:
template<class _Ty> inline
constexpr _Ty&& my_forward(
typename std::remove_reference<_Ty>::type&& _Arg) _NOEXCEPT
{ // forward an rvalue as an rvalue
static_assert(!std::is_lvalue_reference<_Ty>::value, "bad forward call");
return (static_cast<_Ty&&>(_Arg));
}
template<typename T>
T getRValue()
{
return std::remove_reference<T>::type{};
}
template<typename T>
void setValue(T && i)
{
my_forward<T>(getRValue<T>());
}
int main()
{
int i = 1;
setValue(i);
}
要检查何时调用第二个功能,我有错误:
Error C2664 '_Ty my_forward<T>(int &&) noexcept': cannot convert argument 1 from 'int' to 'int &&'
有人知道在哪种情况下知道第二个超载函数(用我的话my_forward)被调用?还是可能是一个很好的例子?顺便说一下,我的编译器是MSVC 2015
谢谢,所有的帮助!
int bad_forward_call() {
return std::forward<int&>(7);
}
这将调用该版本。
注意,我正在转发一个rvalue作为lvalue。不允许。
如果T
是参考类型,您的getRValue
将无法获得RVALUE。
我发现了该功能称为:
的情况my_forward<int&>(8); // This calls forward(typename remove_reference<_Ty>::type&& _Arg)
But it won't compile 'cause we try convert rvalue to lvalue
my_forward<int&&>(8); // This calls forward(typename remove_reference<_Ty>::type&& _Arg)
But it compiles successfully
如果对某人有用,则 std :: forthrom的目的是将操作转发到另一个类或功能。
考虑以下示例:
template<typename T>
void precompute(T & t)
{
std::cout << "lvalue reference";
}
template<typename T,
std::enable_if_t<!std::is_reference<T>::value, bool> = true>
void precompute(T && t)
{
std::cout << "rvalue reference";
}
template<typename T>
void calculate(T && t)
{
precompute(t); // Every time called precompute(T & t)
}
或喜欢:
template<typename T>
void precompute(T & t)
{
std::cout << "lvalue reference";
}
template<typename T,
std::enable_if_t<!std::is_reference<T>::value, bool> = true>
void precompute(T && t)
{
std::cout << "rvalue reference";
}
template<typename T>
void calculate(T && t)
{
precompute(std::move(t)); // Every time called precompute(T && t)
}
您可以看到我们有问题!两个例子都不满足我们。
在第一个示例中,每次都将被称为 lvalue 函数,并且用 rvalue 。
在第二个示例中,每次都将被称为 rvalue 函数,并且不可能先使用 lvalue 。
解决方案是将决策转发为称为函数:
template<typename T>
void precompute(T & t)
{
std::cout << "lvalue reference";
}
template<typename T,
std::enable_if_t<!std::is_reference<T>::value, bool> = true>
void precompute(T && t)
{
std::cout << "rvalue reference";
}
template<typename T>
void calculate(T && t)
{
precompute(std::forward<T>(t)); // Will be called either precompute(T & t) or precompute(T && t) depends on type of t
}
在这种情况下,我们必须确保将其称为适当的版本。这就是为什么我们转发的原因(含义:"请检查t类型,如果是 rvalue -> call rvalue 函数版本,以及它是 lvalue ->呼叫 lvalue function 的版本")此操作为称为函数。
相关文章:
- 为什么我的 std::ref 无法按预期工作?
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- std::unique_ptr 在 GCC 中工作,但不能在 Visual Studio 中编译
- 如何创建一个类,以便向量工作 std::vector<MyClass<int>> v{ 1,2,3 };
- std::数组边界检查如何工作?
- C++ assigment std::list:<typename>:itrator 在 main 中工作,但在方法中它不起作用
- std::strlen 在内部是如何工作的?
- std::async 如何工作:为什么它会调用这么多次复制/移动?
- std::bind,无法让具有单个参数的方法工作
- 为什么"std::is_function_v"不能按预期工作?
- 不使用与左右停止工作命名空间 std 的简单比较
- 对 std::vector 的这种解读是如何工作的?
- std::notify_all_at_thread_exit 如何工作?
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- ZeroMQ 在使用 std::thread 创建工作线程时崩溃
- 使用 std::atomic 标志和 std::condition_variable 在工作线程上等待
- 通过参数启用时,std::enabled_if 如何工作
- 双向链表 std::unique_ptr 类在节点删除时无法按预期工作
- pybind11:无法让 std::list 在 Python 中工作
- std:任何没有RTTI的,它是如何工作的