namespace pairDemo{
template<typename L, typename R>
class pair{
public:
pair(const L& left,const R& right)
:lft(left),rht(right)
{
}
pair(const pair<L,R>& p)
:lft(p.lft),rht(p.rht)
{
}
L left() const{
return lft;
}
R right() const{
return rht;
}
void left(const L& left){
lft = left;
}
void right(const R& right){
rht = right;
}
private:
L lft;
R rht;
};
}
// --------------------------------------------- ------
#include "pairTemp.h"
#include <iostream>
using namespace std;
pairDemo::pair<int, double> func(int x, double y){
pairDemo::pair<int, double> temp(x*2, x+y);
return temp;
}
int main(){
int x = 2; double y = 3.55;
pairDemo::pair<int, double> myPair = func(x,y);
cout << myPair.left() << myPair.right();
}
我有一个问题,即构造函数参数,如果我不声明“const”,函数func()将会出错。我不知道为什么,任何人都可以帮助我。
答案 0 :(得分:2)
由于您将x * 2和x + y传递给构造函数,因此必须将引用声明为const(即只读)。
如果你传递一个非const(即读写)引用,那么函数的代码将能够修改引用以更改传入的任何值。如果你传递x,这是有意义的,y,因为代码可以想象地更新这些值。
但是在这种情况下,更改x * 2或x + y的值没有意义,编译器坚持认为引用是const。
答案 1 :(得分:1)
pair(const L& left,const R& right)
: lft(left), rht(right)
{
}
pairDemo::pair<int, double> func(int x, double y)
{
pairDemo::pair<int, double> temp(x*2, x+y);
return temp; // ^^^ ^^^
} // temporaries here
您的构造函数通过引用获取其参数。在func
中,您将临时对象传递给此构造函数。临时对象只能绑定到 const 引用,这就是为什么在删除const
时出现错误的原因。如果选择按值传递参数,则可以省略const限定符。
答案 2 :(得分:1)
是的,如果您的参数类型为int &
,则无法传递参数x * 2
。拥有非const引用参数允许修改参数,如果您决定忽略这些修改(如果有的话),则需要明确地这样做。
至于将x * 2
传递给const int &
,它可能有点奇怪,但实际发生的是创建一个新的临时变量,分配x * 2
和< em> 变量是传递给函数的东西。在这种情况下,自动创建临时文件没有问题,因为它的值无论如何都不会改变(这就是为什么你有const
,不是吗?)。
答案 3 :(得分:1)
如果从构造函数const
中删除pair::pair(const L& left,const R& right)
,则代码pairDemo::pair<int, double> temp(x*2, x+y);
将无效,因为x*2
的结果被禁止绑定到{{1}并且L& left
被禁止绑定到x+y
。
C ++有这个规则,因为设计人员认为非const引用类型的函数参数应该表明函数可以更改值,并且该更改应该对调用者可见。
考虑:
R& right
如果有人意外使用void foo(int &i) {
i = 3;
}
foo(x); // sets x to 3
foo(1); // sets 1 to 3??? prohibited
或foo
或1
或x+y
这样的临时来电话x*2
,这可能会造成混淆,因此C ++决定做安全事情而不允许这些要编译。
C ++ 11增加了'rvalue references',它们有一些不同的规则。
void bar(int &&i) { // && means 'rvalue reference'
i = 3;
}
bar(1); // sets 1 to 3!
bar(x); // prohibited.
rvalue引用应该意味着该函数正在获得一个临时值,并且它对它的任何作用都不会影响外部世界。现在的危险在于,一个采用右值参考的函数会被意外地用非临时函数调用。因此,规则试图禁止您传递非临时值,如x
。