5

次の C++ コードがありました。宣言内のコンストラクターへの引数は、コンストラクターの定義とは異なる constness を持っていました。

//testClass.hpp
class testClass {
  public:
     testClass(const int *x);
};

//testClass.cpp
testClass::testClass(const int * const x) {}

g++ を使用して警告なしでこれをコンパイルすることができました。64 ビットの solaris に組み込まれている C++ コンパイラでリンカー エラーが発生したことが判明しました。これにより、問題があることに気付きました。

この場合、一致する引数のルールは何ですか? それはコンパイラ次第ですか?

4

4 に答える 4

7

このような場合、 const 指定子は、呼び出し元に対して何も変更しないため 、宣言から省略できます。

実装の詳細のコンテキストにのみ関係します。そのため、宣言ではなく定義にあります。

例:

//Both f and g have the same signature
void f(int x);
void g(const int x);

void f(const int x)//this is allowed
{
}

void g(const int x)
{
}

f を呼び出す人は、変数の独自のコピーであるため、それを const として扱うことを気にしません。

int * const x の場合も同じで、ポインタのコピーです。他の何かを指すことができるかどうかは、発信者にとって重要ではありません。

const int * const で最初の const を省略した場合、それが指しているデータを変更すると呼び出し元にとって重要になるため、違いが生じます。

参照: C++ 標準、8.3.5 パラ 3:

「パラメータ型を変更するcv修飾子は削除されます...そのようなcv修飾子は、関数の本体を持つパラメータの定義にのみ影響します。関数型には影響しません」

于 2009-04-01T15:32:47.550 に答える
5

の同じ違いと考えてください。

//testClass.hpp
class testClass {
  public:
     testClass(const int x);
};

//testClass.cpp
testClass::testClass(int x) {}

これもコンパイルされます。値渡しパラメーターの const-ness に基づいてオーバーロードすることはできません。この場合を想像してください:

void f(int x) { }
void f(const int x) { } // Can't compile both of these.

int main()
{
   f(7); // Which gets called?
}

標準から:

const や volatile の有無のみが異なるパラメーター宣言は同等です。つまり、各パラメーター型の const および volatile 型指定子は、どの関数が宣言、定義、または呼び出されているかを判断するときに無視されます。[例:

typedef const int cInt;
int f (int);
int f (const int); // redeclaration of f(int)
int f (int) { ... } // definition of f(int)
int f (cInt) { ... } // error: redefinition of f(int)

—end example] この方法で無視されるのは、パラメーター型指定の最も外側のレベルにある const および volatile 型指定子だけです。パラメーターの型指定内に埋め込まれた const および volatile 型指定子は重要であり、オーバーロードされた関数宣言を区別するために使用できます. to volatile T」は、「T への参照」、「const T への参照」、および「volatile T への参照」と同様に、別個のパラメータ型と見なされます。</p>

于 2009-04-01T15:32:39.687 に答える
5

この例は、オーバーロード解決セクション 13.1/3b4 で明示的にカバーされています。

const や volatile の有無のみが異なるパラメーター宣言は同等です。つまり、各パラメーター型の const および volatile 型指定子は、どの関数が宣言、定義、または呼び出されているかを判断するときに無視されます。

[例:

typedef const int cInt;
int f (int);
int f (const int); // redeclaration of f(int)
int f (int) { ... } // definition of f(int)
int f (cInt) { ... } // error: redefinition of f(int)

—終わりの例]

だから、それは間違いなくOKです。

于 2009-04-01T15:39:04.680 に答える
0

すでにconstを作っconst int * const xているのと同じではありませんか?const int * x

于 2009-04-01T15:33:15.177 に答える