Consider:
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();
}
For the constructor arguments, if I do not declare "const", the function func() will have an error. Why is that?
If you remove the const
s from the constructor pair::pair(const L& left, const R& right)
, then the code pairDemo::pair<int, double> temp(x*2, x+y);
won't work, because the result of x*2
is prohibited from binding to L& left
, and x+y
is prohibited from binding to R& right
.
C++ has this rule, because the designers felt that function parameters of non-const reference types should indicate that the the function can change the value, and that that change should be visible to the caller.
Consider:
void foo(int &i) {
i = 3;
}
foo(x); // sets x to 3
foo(1); // sets 1 to 3??? prohibited
This could cause confusion if someone accidentally calls foo
with a temporary like 1
or or x+y
or x*2
, so C++ decides to do the safe thing and not allow these to compile.
C++11 adds 'rvalue references' which have some different rules.
void bar(int &&i) { // && means 'rvalue reference'
i = 3;
}
bar(1); // sets 1 to 3!
bar(x); // prohibited.
rvalue references are supposed to mean that the function is getting a temporary value and whatever it does with it will not affect the outside world. Now the danger is that a function taking an rvalue reference would accidentally be called with a non-temporary. Therefore, the rules try to prohibit you from passing in a non-temporary value, like x
.