2012-02-24 10 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(); 
} 

私は、コンストラクタの引数は、私は「CONST」、関数func()を宣言しない場合、エラーを持っているだろうという疑問を持っています。私はなぜ、誰も私を助けることができないdont。

+0

'const'を宣言していない場合は?そして、あなたが得るエラーは...? –

+0

どこでconstを宣言していないのですか?エラーは何ですか?そしてその行はどの行ですか? –

+0

コンストラクタ引数の "const"。私がdelcareをしないと、func()はintをintに変換できないというエラーが発生します。今私は一時的にconstを使うべきであることを知っています。 – titus

答えて

1

あなたはコンストラクタpair::pair(const L& left,const R& right)からconst Sを削除するとx*2の結果はL& leftx+yに結合することが禁止されているので、コードpairDemo::pair<int, double> temp(x*2, x+y);は動作しませんがR& rightに結合することが禁止されます。

非const参照型の関数パラメータは、関数が値を変更でき、その変更が呼び出し側に表示される必要があることをデザイナーが感じていたため、C++にはこの規則があります。

は考える:C++は安全なことを行うことを決定し、これらをコンパイルすることはできませので、誰かが誤って、一時的のような1かまたはx+yまたはx*2fooを呼び出した場合、これは混乱を引き起こす可能性があり

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

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

C++ 11では、いくつかの異なる規則を持つ 'rvalue references'が追加されています。

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

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

右辺値参照は、関数は、一時的な値を取得していると、それはそれでないものは何でも外の世界に影響を与えないことを意味することになっています。今では、危険な参照を取る関数が誤って非一時的に呼び出される危険性があります。したがって、規則はxのような非一時的な値を渡すことを禁止しようとします。

+0

一時的にconstを使うべきであることが分かりました。 – titus

2

コンストラクタにx * 2とx + yを渡すので、参照はconst(つまり読み取り専用)として宣言する必要があります。

非const(つまり読み書き)参照を渡す場合、関数のコードは、渡された値を変更するために参照を変更することができます。これは、渡す場合に意味がありますx、yのようになります。

しかし、この場合、x * 2またはx + yのいずれかの値を変更することは意味をなさないので、コンパイラは参照がconstであると主張します。

+0

constを追加することは決して問題ではありません。あなたが問題に遭遇するconst修飾子を削除しようとすると、それは間違いありません。 ああ、彼がconst、right、nevermindを削除した場合のエラーです。 –

+0

@DanF参照されたオブジェクトを変更できることに依存している場合、 'const'を追加することは問題です。 – hvd

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

1

はい、パラメータがint &の場合、引数x * 2を渡すことはできません。非const参照パラメータを持つと引数の変更が可能になり、変更があればそれを無視する場合は、明示的に行う必要があります。変数が関数に渡されるものであること

const int &x * 2を渡すと、それが動作することを少し奇妙かもしれませんが、どのような実際に起こることは、新たな一時変数が作成されていることで、x * 2を割り当てられ、。この場合、値は変更されないため、一時的に自動的に作成することに問題はありません(そのため、constはありますか?)。

関連する問題