2016-07-06 5 views
-1

構造体ではなく構造体ポインタにconstを適用すると、constは異なる署名を作成するのはなぜですか?constが関数シグネチャの一部になることがあるのはなぜですか?

など。

typedef struct test_s { 
    int foo; 
} test; 

void foo(test *ptr){ 
    return; 
} 

// This is ok 
void foo(const test *ptr){ 
    return; 
} 

void foo(test t){ 
    return; 
} 

//This is an error 
void foo(const test t){ 
    return; 
} 

(GCCバージョン4.9.2でテスト)

具体的には、なぜそれが底つのポインタを有するペアがエラーでない場合、エラーであることです。参照された重複した質問(Functions with const arguments and Overloading)はまた、ポインタの場合は重複しているべきであると主張するようである。それ以前の機能の重複せる

void foo(test t){ 
    return; 
} 

:それは同じであるので

+0

関数がどのような引数を取ることができるかを考えてみましょう。最後の2つはまったく同じ引数を取ることができます。最後のものは内部コピーを一定にすることを任意に決定します(実装の詳細)。最初のものは定数へのポインタを取ることができないので、実際には外部から見て異なる関数です。 –

答えて

1
void foo(const test t){ 
    return; 
} 

はエラーです。


関数の引数がtest*あるとき、あなたはポインタデリファレンスして、それを修正することができます。変更は呼び出し関数で表示されます。

void foo(test *ptr){ 
    ptr->foo = 10; // The state of the object in the calling function 
        // is changed. 
    return; 
} 

関数の引数がconst test*あるとき、あなたはポインタデリファレンスそれにアクセスするが、それを修正しないようにすることができます。

void foo(const test *ptr){ 
    std::cout << ptr->foo << std::endl; // OK 
    ptr->foo = 10;      // Not OK 
    return; 
} 

同じ理由から、あなたがオーバーロードすることができます:

void foo(test& t); 
void foo(const test& t); 

あなたは、あなたがそれを呼び出すとき

void foo(test t); 
void foo(const test t); 

両方が同等の良好な候補であるオーバーロードしようとします。コンパイラは2つの間で曖昧さを取り除くことはできません。さらに、one of the answers to the dupeをご覧ください。それは、最後の2つが同等である理由を述べたC++標準のセクションを引用しています。

+2

thats質問:なぜそれは重複していて、ポインタの例は重複していませんか? – chacham15

+0

@ chacham15コンパイラは、ポインタを非constに、ポインタをconstに区別することができます。あるいは 'const test *'が 'const'ポインタだと思ったのですか? – LogicStuff

+0

@LogicStuffなぜ 'const test *'と 'test *'を区別できるのですが、 'const test'と' test'の間で区別できないのですか? – chacham15

関連する問題