gpt4 book ai didi

c++ - 调用专门的 std::move()

转载 作者:搜寻专家 更新时间:2023-10-31 00:09:18 25 4
gpt4 key购买 nike

我对下面示例中模板参数推导的方式感到困惑。我在本文的其余部分使用术语调用 来暗示实例化和调用

我专业std::move()对于我的自定义类型 my_type我观察到,例如 x类型 my_type :

  1. std::move(x)继续调用通用模板
  2. std::move(static_cast<my_type&&>(x))std::move(std::forward(x))调用特化
  3. 在我没有专门化的情况下,上述所有调用都会调用通用模板

我的问题是:

  • 为什么上面第 1 项中的调用没有调用特化?
  • 在没有专门化的情况下,第 1 项和第 2 项中的调用如何表现相同?

完整代码如下:

#include<iostream>
#include<utility>

struct my_type
{
int x;
};

namespace std
{

// This is the std::move() definition in the preprocessor output:
//
// template <class _Tp>
// inline __attribute__ ((__visibility__("hidden"), __always_inline__)) constexpr
// typename remove_reference<_Tp>::type&&
// move(_Tp&& __t) noexcept
// {
// typedef typename remove_reference<_Tp>::type _Up;
// return static_cast<_Up&&>(__t);
// }

// This is std::move() specialized for my_type
template<>
inline
typename std::remove_reference<my_type>::type&&
move<my_type>(my_type&& t) noexcept
{
std::cout << "Invoke std::move() specialization\n";
return static_cast<typename remove_reference<my_type>::type&&>(t);
}

} // namespace std

int main()
{
auto a = my_type();

std::cout << "Execute 'auto b = std::move(a);'\n";
auto b = std::move(a); // Invokes the generic template

std::cout << "Execute 'auto c = std::move(static_cast<my_type&&>(a));'\n";
auto c = std::move(static_cast<my_type&&>(a)); // Invokes the specialization

return 0;
}

输出:

Execute 'auto b = std::move(a);'
Execute 'auto c = std::move(static_cast<my_type&&>(a));'
Invoke std::move() specialization

最佳答案

当您调用 std::move(a)a 的类型是my_type& , 不是 my_type&& .因此通用 std::move是更好的匹配,因为它可以完全匹配。

如果您更改了 move 的重载看起来像这样:

inline
typename std::remove_reference<my_type>::type&&
move(my_type& t) noexcept
{
std::cout << "Invoke std::move() specialization\n";
return static_cast<typename remove_reference<my_type>::type&&>(t);
}

然后它会被适本地调用(但是通用的会被调用 std::move(static_cast<my_type&&>(a)); )

发生这种情况是因为 generic definition看起来像这样:

template< class T >
constexpr typename std::remove_reference<T>::type&& move( T&& t );

那个T&&是关键。在类型推导的上下文中,它可以同时绑定(bind)到 my_type&。 , my_type&&或任何简历( constvolatile )变体。这就是为什么在没有专门化的情况下,它能够为两个调用调用通用版本。

因此,要真正涵盖所有基础,您需要不止一个重载。不过,可能你最好使用 custom_move受限于您的类型。

关于c++ - 调用专门的 std::move(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43903698/

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