Ric*_*ges 27 c++ language-lawyer visual-studio-2015
给出以下代码:
#include <string>
void foo()
{
std::string s(std::move(""));
}
Run Code Online (Sandbox Code Playgroud)
这与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]
]
Run Code Online (Sandbox Code Playgroud)
暂时忽略移动是多余的,在这种情况下哪个标准库实现更正确?
我的感觉是该类型即""是const char[1]如此std::move应该返回std::remove_reference<const char[1]&>::type&&这将是const char[1]&&.
在我看来,这应该衰败const char*.
或者我是否误解了这些规则?
Sha*_*our 11
这看起来像Visual Studio错误.这归结为std :: move,如果我们查看cppreference页面,它具有以下签名:
template< class T >
typename std::remove_reference<T>::type&& move( T&& t );
Run Code Online (Sandbox Code Playgroud)
它返回:
static_cast<typename std::remove_reference<T>::type&&>(t)
Run Code Online (Sandbox Code Playgroud)
这与草案C++标准部分20.2.4前进/移动助手[前进] 相匹配.
#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 ;
}
Run Code Online (Sandbox Code Playgroud)
使用Wandbox从gcc和clang生成以下答案:
xvalue
Run Code Online (Sandbox Code Playgroud)
以及使用webcompiler从Visual Studio获得的答案:
lvalue
Run Code Online (Sandbox Code Playgroud)
因此Visual Studio对原始代码的错误:
您不能将左值绑定到右值引用
当它试图绑定结果时static_cast<typename std::remove_reference<T>::type&&>(t),std::remove_reference<T>::type&&返回值为std::move.
我没有看到为什么static_cast应该像在Visual Studio案例中那样生成左值的原因.
| 归档时间: |
|
| 查看次数: |
1116 次 |
| 最近记录: |