当我在MSDN上看到这篇文章时,我正在阅读关于右值引用和完美转发:https://msdn.microsoft.com/en-us/library/dd293668.aspx
我的问题是关于这个例子的文章:
#include <iostream>
#include <string>
using namespace std;
template<typename T> struct S;
// The following structures specialize S by
// lvalue reference (T&), const lvalue reference (const T&),
// rvalue reference (T&&), and const rvalue reference (const T&&).
// Each structure provides a print method that prints the type of
// the structure and its parameter.
template<typename T> struct S<T&> {
static void print(T& t)
{
cout << "print<T&>: " << t << endl;
}
};
template<typename T> struct S<const T&> {
static void print(const T& t)
{
cout << "print<const T&>: " << t << endl;
}
};
template<typename T> struct S<T&&> {
static void print(T&& t)
{
cout << "print<T&&>: " << t << endl;
}
};
template<typename T> struct S<const T&&> {
static void print(const T&& t)
{
cout << "print<const T&&>: " << t << endl;
}
};
// This function forwards its parameter to a specialized
// version of the S type.
template <typename T> void print_type_and_value(T&& t)
{
S<T&&>::print(std::forward<T>(t));
}
// This function returns the constant string "fourth".
const string fourth() { return string("fourth"); }
int main()
{
// The following call resolves to:
// print_type_and_value<string&>(string& && t)
// Which collapses to:
// print_type_and_value<string&>(string& t)
string s1("first");
print_type_and_value(s1);
// The following call resolves to:
// print_type_and_value<const string&>(const string& && t)
// Which collapses to:
// print_type_and_value<const string&>(const string& t)
const string s2("second");
print_type_and_value(s2);
// The following call resolves to:
// print_type_and_value<string&&>(string&& t)
print_type_and_value(string("third"));
// The following call resolves to:
// print_type_and_value<const string&&>(const string&& t)
print_type_and_value(fourth());
}
我的问题是,为什么要这样说:
print_type_and_value(s1);
决心:
print_type_and_value<string&>(string& &&t)
如果我的理解是正确的,字符串&amp; &安培;&安培;是左值引用的右值引用。为什么是这样?变量s1是一个左值(它不是临时的,它是可寻址的,它可以从程序的多个部分访问),所以不应该将调用解析为字符串&amp; (一个简单的左值参考)?我不知道双重参考来自哪里。 s1是一个值,而不是一个参考,不是吗?为什么这个调用涉及rvalues?
更笼统地说,我对模板参数何时解析为T&amp; S感到困惑。 &安培;&安培; (右值参考的右值参考?)或T&amp;&amp; &安培; (对右值参考的左值引用?)。
那么,有人可以解释以下内容:
当然,我知道参考崩溃规则,我理解T&amp; &安培;已经崩溃到T&amp;,但我想知道为什么这个例子中的电话解决了T&amp; &安培;&安培;首先。
提前感谢您的帮助!
编辑:
我理解参考折叠的基础知识,但我想知道的一件事就是为什么这个具体的例子表现得如此。
为什么print_type_and_value(s1)解析为print_type_and_value(字符串&amp;&amp;&amp; t),然后折叠为print_type_and_value(字符串&amp; t)?
编辑2:
非常感谢您的链接!我开始理解它了。
我还有一个问题。为什么模板类型评估为字符串&amp;什么时候传递string类型的变量?
编辑3:
我已经重新阅读了您发布的链接,我现在100%得到它。再次感谢!
答案 0 :(得分:1)
参考折叠规则使print_type_and_value<string&>(string& &&t)
等同于print_type_and_value<string&>(string& t)
:没有参考参考。