c++模板问题
C++ Templates Question
谁能解释一下下面代码的输出?
#include <iostream>
template <class T>
void assign(T& t1, T& t2){
std::cout << "First method"<< std::endl;
t1 = t2;
}
template <class T>
void assign(T& t1, const T& t2) {
std::cout << "Second method"<< std::endl;
t1 = t2;
}
class A
{
public:
A(int a) : _a(a) {};
private:
friend A operator+(const A& l, const A& r);
int _a;
};
A operator+(const A& l, const A& r)
{
return A(l._a + r._a);
}
int main ()
{
A a = 1;
const A b = 2;
assign(a, a);
assign(a, b);
assign(a, a + b);
}
输出为
First method
Second method
Second method
我不明白为什么。既然(a+b)不返回const a对象,那么最后一次赋值调用不应该激活第一个版本吗?
表达式不仅有值和类型,而且还有值类别。这个类别可以是
- 左值:这些表达式通常指向已声明的对象、引用、函数或指针的解引用结果。
- 一个xvalue:这些是生成未命名的右值引用的结果。右值引用是由
T&&
而不是T&
创建的。它们是c++ 11的概念,您可以在这里忽略它们。仅为完整起见而提及。 - 右值:这些是强制转换到非引用类型(如
A(10)
)或计算/指定值(如42
或2 + 3
)的结果。
左值引用需要一个左值表达式来初始化。也就是说,以下内容无效:
A &x = A(10);
背后的原因是,只有左值表达式指的是适合并打算在较长时间内保持存活的东西,而不仅仅是在初始化期间。例如,声明的对象在退出其块(如果它是一个局部非静态变量)或直到程序结束(如果它在函数和类之外声明)之前都是活动的。右值表达式A(10)
指向一个在初始化完成时已经死亡的对象。如果你说下面的话,它将没有任何意义,因为像10
这样的纯值根本没有地址,但是引用需要它们绑定的某种身份,实际上是通过在编译器内部获取目标地址来实现的
int &x = 10; // makes totally no sense
但是对于const引用,c++有一个后门。当使用右值初始化时,如果表达式引用对象,则const左值引用将自动延长对象的生存期。如果表达式有一个非对象值,c++用该表达式的值创建一个临时对象,并延长该临时对象的生命周期,将引用绑定到该临时对象:
// lifetime of the temporary object is lengthened
A const& x = A(10);
// lifetime of the automatically created temporary object is lengthened
int const& x = 10;
在你的情况下发生了什么?
现在,在您的例子中,由于您提供了一个临时对象,编译器将选择具有A const&
参数类型而不是A&
参数类型的版本。
(a + b)
返回一个临时对象,因此只能绑定到常量引用。
a+b
返回一个临时的,如果你被允许捕获一个对它的非const引用,你将能够改变它,然后呢?临时对象超出了作用域,对其所做的更改永远无法被应用程序捕获。在c++ 03中,临时变量将被绑定到const引用类型。
相关文章:
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- C++格式化输出问题
- 使用mongocxx驱动程序时包含头文件问题