我已经删除了一些在Visual Studio 2015上无法编译的C++ 11代码到我认为应该编译的以下代码(并且使用clang和gcc):
#include <utility>
void test(const char* x);
int main()
{
const char x[] = "Hello world!";
test(std::forward<const char*>(x));
}
Run Code Online (Sandbox Code Playgroud)
我理解forward这里没有必要打电话.这是从一个更复杂的代码中减少的,它将可变参数中的任何数组衰减到指针并转发所有内容.我确信可以通过模板专业化或SFINAE找到解决这个问题的方法,但是在我走这条路之前,我想知道它是否是有效的C++.编译器是Visual Studio 2015,可以在此在线MSVC编译器上重新创建问题.编译错误是:
main.cpp(13): error C2665: 'std::forward': none of the 2 overloads could convert all the argument types
c:\tools_root\cl\inc\type_traits(1238): note: could be '_Ty &&std::forward<const char*>(const char *&&) noexcept'
with
[
_Ty=const char *
]
c:\tools_root\cl\inc\type_traits(1231): note: or '_Ty &&std::forward<const char*>(const char *&) noexcept'
with
[
_Ty=const char *
]
main.cpp(13): note: while trying to …Run Code Online (Sandbox Code Playgroud) c++ compiler-errors language-lawyer c++11 visual-studio-2015
我试图熟悉完美转发的概念.我已阅读本和这张贴在这里.我相信我对参考折叠概念感到满意.在阅读这篇其他 职位.我提出了以下问题
假设我们有以下示例
Example-1
template <class T>
void foo(T &&t)
{
bar(std::forward<T>(t));
}
Run Code Online (Sandbox Code Playgroud)
我们传递这样的东西
int i= 12;
foo(i);
Run Code Online (Sandbox Code Playgroud)
现在我明白这i将被视为一个int&我不明白的是为什么上面链接中的回答问题提到它将被视为int& &&会崩溃,因为int&.我认为它会被视为int&& &会崩溃以int& 我的理解这两者的返回类型是相同的,但我想获得第一部分的权利.我之所以认为它int&& &不是int& &&下面提到的原因,请纠正我,如果我错了
当我传递这样的东西
int i =12;
foo(i);
Run Code Online (Sandbox Code Playgroud)
然后示例1变成这样的东西
void foo(int &&t)
{
bar(std::forward<int>(&t)); // t is a reference now ------>A
}
Run Code Online (Sandbox Code Playgroud)
现在std :: forward实现就是这个
template<typename T> // For lvalues (T is T&),
T&& std::forward(T&& param) // take/return lvalue …Run Code Online (Sandbox Code Playgroud) 例如
template <typename T>
void function(T&& arg)
Run Code Online (Sandbox Code Playgroud)
有人可以详细解释一下函数签名如何结束为左值的 T& 和传入的右值的 T&& 吗?我知道以某种方式(需要标准线) T -> T& 在左值的情况下和 T -> T 在重估的情况下,然后通过组合 & 和 && 它导致左值/右值引用。
考虑用于检查参数值等的"契约"函数:
template< class T >
const T& AssertNotEmpty( const T& val )
{
//raise hell if val empty/0/...
return val;
}
Run Code Online (Sandbox Code Playgroud)
例如,可以使用如下:
void foo( const std::shared_ptr< int >& val )
{
AssertNotEmpty( val );
//use *val
}
class Bar98
{
public:
Bar98( const std::shared_ptr< int >& val ) : myVal( AssertNotEmpty( val ) ) {}
private:
std::shared_ptr< int > myVal;
};
std::shared_ptr< int > x;
//...
AssertNotEmpty( x ); //(1)
Run Code Online (Sandbox Code Playgroud)
现在进入C++ 11,我们希望Bar98按值获取构造函数参数并从中移出:
class Bar11
{
public:
Bar11( std::shared_ptr< int > …Run Code Online (Sandbox Code Playgroud)