16

一時オブジェクトは定数参照にのみ割り当てることができると聞きました。

しかし、このコードはエラーになります

#include <iostream.h>    
template<class t>
t const& check(){
  return t(); //return a temporary object
}    
int main(int argc, char** argv){

const int &resCheck = check<int>(); /* fine */
typedef int& ref;
const ref error = check<int>(); / *error */
return 0;
}

getのエラーはinvalid initialization of reference of type 'int&' from expression of type 'const int'

4

5 に答える 5

21

これ:

typedef int& ref;
const ref error;

あなたが思っていることをしません。代わりに検討してください:

typedef int* pointer;
typedef const pointer const_pointer;

のタイプconst_pointerint* const、ではありません const int *。つまり、const T「Tが不変であるタイプを作成する」と言っている場合。したがって、前の例では、ポインター(ポインターではない)は不変になっています。

参照することはできませconstvolatile。これ:

int& const x;

は無意味なので、参照にcv-qualifiersを追加しても効果はありません。

したがって、errorタイプはint&です。に割り当てることはできませんconst int&


コードには他にも問題があります。たとえば、これは確かに間違っています。

template<class t>
t const& check()
{
    return t(); //return a temporary object
}

ここで行っているのは、関数が。を返すときにその存続期間を終了する一時オブジェクトへの参照を返すことです。つまり、referandにオブジェクトがないため、これを使用すると未定義の動作が発生します。これは次のようなものに勝るものはありません。

template<class t>
t const& check()
{
    T x = T();
    return x; // return a local...bang you're dead
}    

より良いテストは次のようになります。

template<class T>
T check()
{
    return T();
}

関数の戻り値は一時的なものであるため、一時的なものを定数参照に実際にバインドできるかどうかをテストできます。

于 2010-09-27T08:06:22.610 に答える
8

これは、英語の文法が機能するため、英語を話す人々にとって非常に一般的な間違いです。

C++ 構文が両方を許可することは、非常に残念なことだと思います。

const int // immutable int
int const // immutable int

同じ意味を持つこと。

実際には簡単にはなりません。また、次の理由から構成可能ではありません。

const int* // mutable pointer to immutable int
int* const // immutable pointer to mutable int

確かに同じ意味ではありません。

そして、これは、@GMan が説明しているように、残念ながらここで発生します。

将来この種のエラーを回避したい場合は、型 (constおよびvolatile) を右側typedefで修飾する習慣を身に付けてください。そうすれば、 aを単純なテキスト置換として扱うことができます。

于 2010-09-27T08:27:39.347 に答える
7

constの修飾子const ref errorが無視されるため、コードでエラーが発生します8.3.2/1

typedef(7.1.3)またはテンプレート型引数(14.3)を使用してcv-qualifiersが導入された場合を除いて、Cv-qualified参照は不正な形式になります。この場合、cv-qualifiersは無視されます。`

したがってerror、タイプint&はありませんconst int&

于 2010-09-27T08:07:49.170 に答える
3

Right Left Ruleとの一貫性を維持するために、私は「cv」修飾子をそのように使用することを好みます。

int const x = 2; // x is a const int (by applying Right Left rule)

int const *p = &x;  // p is a pinter to const int

const ref error = check<int>();あなたの例では、私はそのように書きます

ref const error = check<int>(); // parsed as error is a const reference to an integer

@Prasoon Saurav が指摘したように、typedef を介して導入された場合、cv 修飾子は無視されます。これは、@GMan も言うように、cv 修飾参照は形式が正しくないためです。

したがって、宣言は事実上次のようになりますが、これはもちろんエラーです。

   int &error = check<int>(); 

詳しくはこちらをご覧ください。

于 2010-09-27T08:28:39.153 に答える
0

これはコンパイルされます:

typedef const int&ref;
refエラー=check<int>();

VC ++コンパイラは、エラーの説明を提供します。参照型に適用される修飾子。無視されます。参照型は定数として宣言する必要があります。constは後で適用できません。

于 2010-09-27T08:08:20.340 に答える