3

以下のコードの動作を観察していますが、これは簡単には説明できず、理論をよりよく理解したいと考えています。この特定の状況をカバーするオンライン ドキュメント ソースや既存の質問が見つからないようです。参考までに、Visual Studio C++ 2010 を使用して、次のコードをコンパイルして実行しています。

#include <iostream>
using namespace std;

struct Bottom_Class
{
    template<typename This_Type>
    void Dispatch()
    {
        // A: When this comment is removed, the program does not compile
        //    citing an ambiguous call to Print_Hello
        // ((This_Type*)this)->Print_Hello();

        // B: When this comment is removed instead, the program compiles and
        //    generates the following output:
        //    >> "Goodbye from Top Class!"
        // ((This_Type*)this)->Print_Goodbye<void>();
    }

    void Print_Hello() {cout << "Hello from Bottom Class!" << endl;}

    template<typename This_Type>
    void Print_Goodbye() {cout << "Goodbye from Bottom Class!" << endl;}
};

struct Top_Class
{
    void Print_Hello() {cout << "Hello from Top Class!" << endl;}

    template<typename This_Type>
    void Print_Goodbye() {cout << "Goodbye from Top Class!" << endl;}
};

template<typename Top_Type,typename Bottom_Type>
struct Merged_Class : public Top_Type, public Bottom_Type {};

typedef Merged_Class<Top_Class,Bottom_Class> My_Merged_Class;

void main()
{
    My_Merged_Class my_merged_object;

    my_merged_object.Dispatch<My_Merged_Class>();
}

テンプレート化されたメンバー関数とテンプレート化されていないメンバー関数の場合で、これが異なるのはなぜですか?

Top_Class::Print_Goodbye() が Bottom_Class::Print_Goodbye() ではなく適切なオーバーロードであることを (テンプレート化された場合に) コンパイラはどのように判断しますか?

よろしくお願いいたします。

4

2 に答える 2

3

両方のコメント (AFAIK が正しく) は、GCC 4.6.3 でコンパイル エラーを生成します。Microsoft コンパイラが何か間違ったことをしている可能性があります。

➜  scratch  g++ -O2 templ.cc
templ.cc: In member function ‘void Bottom_Class::Dispatch() [with This_Type = Merged_Class<Top_Class, Bottom_Class>]’:
templ.cc:42:48:   instantiated from here
templ.cc:16:9: error: request for member ‘Print_Goodbye’ is ambiguous
templ.cc:22:10: error: candidates are: template<class This_Type> void Bottom_Class::Print_Goodbye()
templ.cc:30:10: error:                 template<class This_Type> void Top_Class::Print_Goodbye()
于 2012-07-28T00:09:49.780 に答える
1

Dispatchメソッドでは、This_Typeと同じMy_Merged_Classです。にはの名前をMy_Merged_Class持つ2 つのメソッドがありますPrint_Hello。もちろん、コンパイラはそれらを区別するのに問題があります。

Print_Helloテンプレート置換後のinの呼び出しDispatchは次のようになります。

((My_Merged_Class*)this)->Print_Hello();

上記の置換が、あいまいさがある理由をよりよく理解するのに役立つことを願っています. 同じ問題実際には で発生するはずPrint_Goodbyeですが、使用しているコンパイラのバグが原因である可能性があります。

于 2012-07-28T00:32:32.083 に答える