【发布时间】:2017-10-09 18:21:08
【问题描述】:
我对以下示例中如何进行模板参数推导感到困惑。我在本文的其余部分使用术语 invoke 来暗示 实例化和调用。
我将std::move() 专门用于我的自定义类型my_type,我观察到,例如x 类型为my_type:
-
std::move(x)继续调用通用模板 -
std::move(static_cast<my_type&&>(x))或std::move(std::forward(x))调用专业化 - 在我没有专长的情况下,上述所有调用都会调用通用模板
我的问题是:
- 为什么上面第 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?如果你希望你的脚趾是可移动的,只需提供一个移动构造函数和移动赋值运算符。 -
@NathanOliver,我同意自定义移动构造函数和赋值运算符是正确的方法。但无论如何,我无法解释我在观察什么。这就是我发布问题的原因。
-
@NathanOliver:我认为脚趾已经可以移动了 :-)
-
@AndyG 什么是脚趾?
-
@ACE:这是附着在你脚上的一种摇摆不定的东西;-)
标签: c++ c++11 stl move-semantics template-specialization