这种在C++ 03中模拟移动语义的方法有多安全?

Meh*_*dad 9 c++ move-semantics c++11 c++03

使用这个答案,我发明了自己的基于C++ 03模拟移动语义的方法swap.

首先,我检测移动语义(即C++ 03的可用性):

#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) ||  \
    defined(_MSC_VER) && _MSC_VER >= 1600
#define HAS_MOVE_SEMANTICS 1
#elif defined(__clang)
#if __has_feature(cxx_rvalue_references)
#define HAS_MOVE_SEMANTICS 1
#else
#define HAS_MOVE_SEMANTICS 0
#endif
#else
#define HAS_MOVE_SEMANTICS 0
#endif
Run Code Online (Sandbox Code Playgroud)

然后我有条件地定义一个名为的宏move:

#if !HAS_MOVE_SEMANTICS
#include <algorithm>
namespace _cpp11_detail
{
    template<bool B, class T = void> struct enable_if;
    template<class T> struct enable_if<false, T> { };
    template<class T> struct enable_if<true, T> { typedef T type; };
    template<class T>
    inline char (&is_lvalue(
        T &, typename std::allocator<T>::value_type const volatile &))[2];
    inline char (&is_lvalue(...))[1];
    template<bool LValue, class T>
    inline typename enable_if<!LValue, T>::type move(T v)
    { T r; using std::swap; swap(r, v); return r; }
    template<bool LValue, class T>
    inline typename enable_if<LValue, T>::type move(T &v)
    { T r; using std::swap; swap(r, v); return r; }
    template<bool LValue, class T>
    inline typename enable_if<LValue, T>::type const &move(T const &v)
    { return v; }
}
using _cpp11_detail::move;
namespace std { using _cpp11_detail::move; }
// Define this conditionally, if C++11 is not supported
#define move(...) move<  \
    (sizeof((_cpp11_detail::is_lvalue)((__VA_ARGS__), (__VA_ARGS__))) != 1)  \
>(__VA_ARGS__)
#endif
Run Code Online (Sandbox Code Playgroud)

然后我像这样使用它:

#include <vector>

std::vector<int> test(std::vector<int> v) { return std::move(v); }

int main()
{
    std::vector<int> q(5, 5);
    int x = 5;
    int y = std::move(x);
    std::vector<int> qq = test(std::move(test(std::move(q))));
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,这种方法在实践中有多安全(假设它编译好)

  1. 是否有任何实际场景可能无法在C++ 03中正常工作但在C++ 11中无法正常工作?

  2. 反之亦然 - 它可以在C++ 11中正常工作但在C++ 03中失败吗?

(注意:我正在寻找一个实际的答案,而不是语言律师的答案.我知道定义新成员在namespace std技术上是未定义的,但在实践中不会导致任何编译器出现问题,所以我找不到为了这个问题的目的值得担心.我担心偶然的悬挂引用等情况.)

Meh*_*dad 0

执行摘要似乎是“只要按常规方式使用它就是安全的”。