以下链接提供了4种形式的引用折叠(如果我是正确的,这些是唯一的4种形式):http://thbecker.net/articles/rvalue_references/section_08.html.
从链接:
- A &&成为A&
- A &&&成为A&
- A &&&成为A&
- A && &&成为A &&
虽然我可以做出有根据的猜测,但我想简要解释这些参考折叠规则背后的基本原理.
一个相关的问题,如果可能的话:在典型的实际用例中,这些STL实用程序(例如,等)在C++ 11内部使用这些引用折叠规则吗?(注意:我特别询问C++ 11中是否使用了引用折叠规则,而不是C++ 03或更早版本.)std::move()std::forward()
我问这个相关的问题,因为我知道这样的C++ 11实用程序std::remove_reference,但我不知道是否与std::remove_referenceC++ 11中常规使用的引用相关的实用程序,以避免需要引用 - 折叠规则,或者它们是否与参考折叠规则一起使用.
有std::pair引用是否有效?特别是,赋值运算符是否存在问题?根据这个链接,似乎没有对operator =进行特殊处理,因此无法生成默认的assignement运算符.
我希望有一个pair<T&, U&>并且能够为其分配另一对(值或引用)并修改指向的对象.
在具有泛型类型T的C++模板中,我可以使用
const T &
Run Code Online (Sandbox Code Playgroud)
获取对常量T的引用.但是,如果现在T本身是引用类型(例如T = int&),则上述术语解析为
int &
Run Code Online (Sandbox Code Playgroud)
而不是
const int &
Run Code Online (Sandbox Code Playgroud)
这很有意义,因为任何引用本身都是不变的.但是,还有一种方法需要一个
const T &
Run Code Online (Sandbox Code Playgroud)
如果T本身是参考类型?
编辑:要评估的示例代码(g ++编译器):
template <typename T> class TemplateClass
{
public:
void foo(const T &bar) { }
};
int main()
{
TemplateClass<int &> x;
x.foo(0); // <-- compile error: no conversion from int to int&
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我听过一些关于引用参考问题和这个解决方案的内容.我对C++委员会术语不是很了解,但我理解链接中的"Moved to DR"注释意味着这是符合标准的编译器应遵循的当前解释.
我有这个我无法理解的示例代码:
template <typename T>
struct C {
void f(T&) { }
void f(const T&) { }
};
int main() {
C<int> x; // OK
C<int&> y; // compile error: f cannot be overloaded
C<const int&> z; // compile error: f cannot be overloaded
}
Run Code Online (Sandbox Code Playgroud)
我理解错误C<const int&>:使用DR#106中的规则,我们得到两个具有相同签名f(const int&)的方法.我不能得到的是C<int&>:它不应该生成完全相同的代码C<int>(至少根据Stroustrup的分辨率)?
我需要从绑定成员函数创建一个谓词,所以我将它包装在一个boost::function<bool(SomeObject const &)>.这看起来很好,但是我还需要在一个案例中否定它.然而
boost::function<bool(SomeObject const &)> pred;
std::not1(pred);
Run Code Online (Sandbox Code Playgroud)
不能在MSVC++ 9.0(Visual Studio 2008)下编译,抱怨对引用的引用无效:
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : warning C4181: qualifier applied to reference type; ignored
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : error C2529: '_Left' : reference to reference is illegal
Run Code Online (Sandbox Code Playgroud)
问题是boost::function定义argument_typeas SomeObject const &和std::unary_negate<_Fn1>实例化由std::not1内部尝试使用const typename _Fn1::argument_type&和编译器拒绝它因为T::argument_type已经是一个引用.我确信这应该在C++ 11下编译,但这只是旧的编译器,只是C++ 03.所以我想知道它是谁的错:
unary_negate了const typename Predicate::argument_type& x参数),argument_type即使实际参数是或者,也不应该引用 …以下代码显示,如果const使用引用类型(例如,int&)实例化采用ref-to-参数的模板,则该参数不是const:
#include <iostream>
template<typename T>
void f(const T& arg) // arg isn't const if T is a reference type
{
arg = -1;
}
int main()
{
int x = 0;
f<int&>(x); // instantiate f with reference type
std::cout << x << '\n'; // prints -1 under gcc, clang, and msvc
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
我的猜测是,最初的类型argisint & const &并且它以某种方式转换为int&. 如果是这样,就标准而言,这究竟是如何发生的?如果这不是正在发生的事情,那是什么?