8

次の例のように継承のチェーンを使用すると、最も深いベースの変数を問題なく使用できます。

    class A { public: int x; };
    class B : public A { };
    class C: public B { public: void Do() { cout << x << endl; } };

再帰的な可変個引数テンプレートクラスで同じことをすると、変数にアクセスできませんでした。変数にアクセスする方法と、変数が表示されなかった理由はありますか?

    template <class ...Parms>
    class Example;

    template <class Head, class ...Parms>
    class Example<Head, Parms...>: public Example<Parms...>
    {
    };

    template <>
    class Example<>
    {
        public:
        int x;
    };

    template <class ...Parms>
    class Last: public Example<Parms...>
    {
        void Do() { cout << x << endl; }
    };

クラスのインスタンスがインスタンス化される前にコンパイルが失敗します!

4

1 に答える 1

8

xこの場合、は依存名であるため、if asにアクセスする必要がありますthis->x(または、クラス定義にusing宣言を入れてスコープに入れる必要があります。

using Example<Params...>::x;

編集

この理由は、規格の[temp.res]で説明されています。基本的に:コンパイラーがテンプレートを解析しているとき、それはちょうどを見るxxテンプレートのパラメーターに依存していることを知る方法はありません(これは、テンプレートに依存している基本クラスからのものであるため、あなたの場合はそうなります)。したがって、コンパイラーはx、テンプレートを解析するときに認識しているものを使用して解決しようとし、失敗します。

書くことは、それがクラスのメンバーを指すことをthis->x示します。x特定のクラスの基本クラスはテンプレートパラメーターに依存するため、コンパイラーはx、テンプレートを解析するときに解決できないことを認識し、テンプレートがインスタンス化されるまで解決を延期します。その時点で、テンプレートの引数は既知です。

同じことが。にも当てはまりますusing Example<Params...>::x;。これは、テンプレートパラメータに依存するコンパイラにもx通知し、その解決はインスタンス化に延期する必要があります。

于 2012-11-14T11:22:46.373 に答える