c++ - 字符串文字的 std::move - 哪个编译器是正确的?

标签 c++ visual-studio-2015 language-lawyer

给定以下代码:

#include <string>
void foo()
{
  std::string s(std::move(""));
}

这可以使用 apple clang (xcode 7) 编译,但不能使用 Visual Studio 2015 编译,这会产生以下错误:

error C2440: 'return': cannot convert from 'const char [1]' to 'const char (&&)[1]'
note: You cannot bind an lvalue to an rvalue reference
main.cpp(4): note: see reference to function template instantiation 'const char (&&std::move<const char(&)[1]>(_Ty) noexcept)[1]' being compiled
    with
    [
        _Ty=const char (&)[1]
    ]

暂时忽略移动是多余的,在这种情况下哪个标准库实现更正确?

我的感觉是 "" 的类型是 const char[1]所以std::move应该返回 std::remove_reference<const char[1]&>::type&&这将是 const char[1]&& .

在我看来,这应该衰减到 const char* .

还是我误解了规则?

最佳答案

这看起来像一个 Visual Studio 错误。这归结为 std::move如果我们查看 cppreference 页面,它具有以下签名:

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

然后它返回:

static_cast<typename std::remove_reference<T>::type&&>(t) 

符合草案 C++ 标准部分 20.2.4前进/移动助手[前进]。

使用 code I grabbed from here我们可以看到下面的例子:

#include <iostream>

template<typename T>
struct value_category {
    // Or can be an integral or enum value
    static constexpr auto value = "prvalue";
};

template<typename T>
struct value_category<T&> {
    static constexpr auto value = "lvalue";
};

template<typename T>
struct value_category<T&&> {
    static constexpr auto value = "xvalue";
};

// Double parens for ensuring we inspect an expression,
// not an entity
#define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value


int main()
{   
    std::cout << VALUE_CATEGORY( static_cast<std::remove_reference<const char[1]>::type&&>("") ) << std::endl ;

}

使用 Wandbox 从 gcc 和 clang 生成以下答案:

xvalue

这个答案来自 Visual Studio 使用 webcompiler :

lvalue

因此来自 Visual Studio 的原始代码错误:

You cannot bind an lvalue to an rvalue reference

当它试图绑定(bind) static_cast<typename std::remove_reference<T>::type&&>(t) 的结果时至std::remove_reference<T>::type&&这是std::move的返回值.

我看不出 static_cast 的任何原因应该像在 Visual Studio 案例中那样生成一个左值。

关于c++ - 字符串文字的 std::move - 哪个编译器是正确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34160614/

相关文章:

c++ - GPU编程策略

c# - 在 C# 中选择 MySQL 数据

visual-studio-2015 - 减少Visual Studio 2015中的左边距

c++ - 在指向类类型对象的指针上使用 delete-expression 的合法性,其生命周期已结束的平凡析构函数/标量类型

c++ - 我想优化这个短循环

c++ - “generate”不是窗口的<random>头文件中 'std::random_device'的成员

c++ - 结束另一个线程中使用的对象的生命周期

c++ - 使用可变参数模板重载函数模板 : Intel c++ compiler version 18 produces different result from other compilers. intel 错了吗?

c++ - 需要解决限制 : abstract class cannot be used for return types

asp.net-mvc - VS2015 - IntelliSense 无法在类库中的 Razor View 中工作