ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

C言語とC++言語コミュの[C++] 多重定義解決規則(overload resolution rules)

  • mixiチェック
  • このエントリーをはてなブックマークに追加
#include <cstdio>
#include <cctype>

template<class T> struct Test {
  T hoge;
  const char *ptr() const { return hoge; }
  char *ptr() { return hoge; }
};

int main( int ac, char *av[] ) {
  char str[] = "char*";
  Test<char*> editor = { str };
  *editor.ptr() = toupper( *editor.ptr() );
  puts( editor.ptr() );

  const Test<const char*> const_test = { "const char*" };
  puts( const_test.ptr() );

  Test<const char*> test = { "const char*" };
  puts( test.ptr() ); // here

  return 0;
}

このコードを g++ 3.3.4 でコンパイルすると、"const_test.ptr()" は
ptr() const を呼び出すのでエラーにはならないのですが、"test.ptr()"
(コメントを付けた行) は、const でない ptr() を呼び出そうとしてエラーになります。

このとき、ptr() const を先に探せばエラーにならないのに、
const なしの関数を先に探すようになっている理由が思いつかず、
悶々としています。どなたか背景を教えて頂けませんでしょうか。

また、const member function を多重定義した場合の解決の規則を
C++ 第3版/Stroustrup/(株)ロングテール他訳/ASCII や web で探して
みたのですが見つけられなかったため、あわせて教えて頂ければ幸いです。

コメント(11)

ご質問の直接の回答になっておらず恐縮ですが、
この問題について、templateは本質的なのでしょうか。
つまり、templateクラスでなければ、この問題は発生しないのでしょうか。
そうであれば、その旨を明記されたほうが、書き込みをされる方にとって少しでも助けになりますし、
そうでなければ、できるだけ例題は小さく、問題が起こるのに不要なコードは取り除いて、質問したほうがよいと思います。
本当にこのコードコンパイルできますか?

我が家のgcc 3.4.2 ではコンパイルできませんでした。
> $ g++ const_ptr001.cpp -o const_ptr001
> const_ptr001.cpp: In member function `char* Test<T>::ptr() [with T = const char*]':
> const_ptr001.cpp:21: instantiated from here
> const_ptr001.cpp:8: error: invalid conversion from `const char*' to `char*'
>はるさん

template で多重定義された関数を検索する順序(解析規則)を知る、
というのが本質なので template は必要という認識です。
(解りにくくてすみません。他の例でも同様の現象を起こる例が
あるかも知れないのですが、如何せん私が知らないのです。orz)
>やえもんさん

はい、
> (コメントを付けた行) は、const でない ptr() を呼び出そうとしてエラーになります。
と書いたとおり、僕もやえもんさんと同じエラーが出てます ^^;
# "puts( test.ptr() );" の行をコメントアウトすればコンパイルできます。

この時の、const_test.ptr() の呼び出しはOKで、test.ptr() の呼び出しはNG、
というのが、多重定義された関数の解析規則によって決められるようなのですが、
その仕様とか背景とかが解らなくて質問させて貰っています。
>人柱さん (と呼んでしまって良いんでしょうか?^^;)

お〜、かなり納得できそうな説明ありがとうございます。m(__)m
ちょっとまだ "this を引数で渡さないと…" というところの背景が見えてない
(徹夜明けで廻りが悪い...orz)ので、快晴とまでは行ってませんが、かなり
晴れて来てます。しばし休息後に考えさせて頂きます。

> ちなみに、これにテンプレートは、関係ありません。

あら、そうなのですか。。ちょっとこちらもよーく考えてみます。ありがとうございます。
> このとき、ptr() const を先に探せばエラーにならないのに、
> const なしの関数を先に探すようになっている理由が思いつかず、
> 悶々としています。どなたか背景を教えて頂けませんでしょうか。

returnの型を使って多義を解決しようとするのが
そもそもの間違いです。
C++はその期待に答えませんから。
const char * を char * へ変換できません,というだけではないですか?

Test<const char*> test = { "const char*" };

↑を,

Test<char*> test = { "const char*" };

↑の様に修正しただけで通りましたが。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

C言語とC++言語 更新情報

C言語とC++言語のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング