2012-02-24 60 views
0
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; 
}; 
} 

// ------------------------------------------- --------关键字“const”如何工作?

#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(); 
} 

我有一个问题,构造函数的参数,如果我不宣布“常量”,函数func()将有一个错误。我不知道为什么,任何人都可以帮助我。

+0

如果你没有声明什么'const'?你得到的错误是...? – 2012-02-24 21:59:38

+0

你不在哪里声明const,什么是错误,以及错误是哪一行? – 2012-02-24 22:00:11

+0

构造函数参数中的“const”。如果我没有delcare,func()会有一个错误,它不能将int转换为int&。现在我知道临时应该使用const了。 – titus 2012-02-24 22:42:47

回答

1

如果从构造pair::pair(const L& left,const R& right)删除const当时的因为x*2结果绑定到L& leftx+y禁止代码pairDemo::pair<int, double> temp(x*2, x+y);将无法​​正常工作从结合R& right禁止。

C++有此规则,因为设计者认为非const引用类型的函数参数应表明,该函数可以改变值,并且该该变化应给调用者可见。

考虑:

void foo(int &i) { 
    i = 3; 
} 

foo(x); // sets x to 3 
foo(1); // sets 1 to 3??? prohibited 

这可能会导致混乱,如果有人不小心与临时像1或或x+yx*2调用foo,所以C++决定做安全的事情,而不是让这些编译。

C++ 11增加了'右值引用',它们有一些不同的规则。

void bar(int &&i) { // && means 'rvalue reference' 
    i = 3; 
} 

bar(1); // sets 1 to 3! 
bar(x); // prohibited. 

右值引用应该表示该函数正在获取一个临时值,并且它所做的任何操作都不会影响外界。现在危险的是,一个采用右值引用的函数会被意外地用非临时函数调用。因此,这些规则试图禁止您传入非临时值,如x

+0

现在我知道临时应该使用const。 – titus 2012-02-24 22:45:51

2

由于您将x * 2和x + y传递给构造函数,因此必须将引用声明为const(即只读)。

如果您传递的是非const(即读写)引用,那么函数的代码将能够修改引用以更改任何传入的值。如果您正在传递x,y,因为代码可以想象更新这些值。

但是在这种情况下,更改x * 2或x + y的值是没有意义的,编译器坚持引用是const。

+0

添加const从来不是一个问题,我相信,当你试图去除你碰到的const限定符时遇到麻烦,对吧? 哦,但错误是如果他删除const,正确,从不知道 – 2012-02-24 22:04:25

+0

@DanF如果您依赖于能够修改引用的对象,那么添加'const'是一个问题。 – hvd 2012-02-24 22:05:21

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限定符。

+0

谢谢,我知道。 – titus 2012-02-24 22:37:14

1

是的,如果您有类型int &的参数,则无法传递参数x * 2。使用非const引用参数可以修改参数,如果您决定忽略这些修改(如果有),则需要明确地进行修改。

至于传递x * 2const int &,它可能是一个有点奇怪的作品,但实际发生的事情是,一个新的临时变量被创建,分配x * 2变量是什么获取传递给函数。在这种情况下,自动创建一个临时对象没有问题,因为它的值不会被改变(这就是为什么你有const,不是吗?)。