48890


int main関数の方で `derive<int> d;`
と宣言すると[純枠仮想関数をオーバーライドするものがありません]というエラー出ます、純枠仮想関数を派生先で定義しているのにも関わらずエラーでる理由がわかりません。教えていただけますでしょうか？

[code]

    template<class type,class typeb>
    class base {
    private:
    
    protected:
    
    public:
        base(){ }
    
        virtual void f(int x) {
            typeb a = x;
            std::cout << "仮想関数"<< a <<"\n";
        }
    
        virtual type f2(type x)const = 0;//純粋仮想関数
    
    };
    
    template<class typec> 
    class derive : public base<class type,class typeb> {
    
    public:
        derive(){ }
    
            void f(int x) {
            std::cout << "派生"<< x<<"\n";
        }
    
        typec f2(typec x)const {
            std::cout << x;
    
            return x;
        }
    
    };
    
[/code]


CC BY-SA 4.0
2018-10-02T03:59:57.507
48889
2018-10-02T23:22:42.127
2018-10-02T23:22:42.127
4236
question
c++
テンプレートクラスの派生で純枠仮想関数をオーバーライドするものがありません


純枠仮想関数以前の問題として、[テンプレート仮引数](https://en.cppreference.com/w/cpp/language/template_parameters)と[プロトタイプ宣言](https://en.cppreference.com/w/cpp/language/class#Forward_declaration)を混同し、無茶苦茶なコードになっています。これらを区別するため、質問文のテンプレート仮引数をPascal形式で書き直します。

[code]

    template<class Type, class Typeb>
    class base {
    private:
    protected:
    public:
        base(){ }
        virtual void f(int x) {
            Typeb a = x;
            std::cout << "仮想関数"<< a <<"\n";
        }
        virtual Type f2(Type x)const = 0;//純粋仮想関数
    };
    
[/code]

テンプレートクラス`base`はテンプレート仮引数`Type`と`Typeb`を取ります。これらはテンプレートが実体化される際に指定します。

[code]

    template<class Typec> 
    class derive : public base<class type, class typeb> {
    public:
        derive(){ }
        void f(int x) {
            std::cout << "派生"<< x<<"\n";
        }
        Typec f2(Typec x)const {
            std::cout << x;
            return x;
        }
    };
    
[/code]

テンプレートクラス`derive`はテンプレート仮引数`Typec`を取ります。これらはテンプレートが実体化される際に指定します。テンプレートクラス`derive`の親クラスは`base<type,
typyeb>`です。`type`と`typeb`は後ほどこの名称でクラス定義されることがプロトタイプ宣言されています。  
もう少し分かり易く書き直すと以下と同等です。

[code]

    class type;   // 後で定義する
    class typeb;  // 後で定義する
    
    template<class Typec> 
    class derive : public base<type, typeb> {
    public:
        derive(){ }
        void f(int x) {
            std::cout << "派生"<< x<<"\n";
        }
        Typec f2(Typec x)const {
            std::cout << x;
            return x;
        }
    };
    
[/code]

質問文のコード片では推測することしかできませんが、恐らくクラス`type`やクラス`typeb`を定義する予定はないと思われます。その場合、純枠仮想関数が存在しなくても最終的にコンパイルエラーになります。

* * *

なお、本題の質問についてですが、親クラスが`base<type, typyeb>`でテンプレート実体化されているため、純粋仮想関数は`virtual
type f2(type x) const =
0;`となっています。ですので、`derive`においても`Typec`ではなく`type`を引数・戻り値に持つ関数を用意しなければなりません。

> 純枠仮想関数を派生クラスでtypeにするためにはどのようにコードを変更すればいいのでしょうか？

文字通り`type f2(type
x)const`とすれば質問の純粋仮想関数の問題は解決します。合わせて`type`クラスを使用することになるためプロトタイプ宣言でなくクラス定義が必要です。

[code]

    class type{
        // 定義する
    }
    class typeb; // 後で定義する
    
    template<class Typec> 
    class derive : public base<type, typeb> {
    public:
        derive(){ }
        void f(int x) {
            std::cout << "派生"<< x<<"\n";
        }
        type f2(type x)const {
            std::cout << x;
            return x;
        }
    };
    
[/code]


CC BY-SA 4.0
2018-10-02T04:33:50.860
48890
2018-10-02T05:06:28.117
2018-10-02T05:06:28.117
4236
4236
48889
answer


sayuri さんの回答で言い尽くされているので蛇足っす

[code]

    template<class typec> 
    class derive : public base<class type,class typeb> { ... };
    
[/code]

こう記述したプログラマの内心がどうあれコンパイラがこのコードを見て判断するのは  
\- `typec` は型引数だな  
\- `class type { ... };` という真のクラスがあって、それを使うんだな  
\- `class typeb { ... };` という真のクラスがあって、それを使うんだな  
\- クラステンプレート `base<>` を `type` と `typeb` で具現化するんだな  
ということになります。

`class type` がテンプレート型引数と読むことはありません。もしこの `type` が型引数であってほしいのであれば `template`
直後に型引数であることの明示が必要です。`template` の型引数を `typename` で書くように心がけておくと

[code]

    // 誤ってますがもしこう書いたとしたら
    template<typename typec>
    class derive : public base<typename type, typename typeb> { ... };
    
[/code]

と書いたであろうはずで、これならコンパイラにも `class type { ... };` とは読めなくなりエラーが発生します。

[c++、テンプレートのtypenameとclassの違いについて知りたい](https://ja.stackoverflow.com/questions/47944/)  
こんなところに差がありましたってことで。


CC BY-SA 4.0
2018-10-02T07:40:24.910
48898
2018-10-02T07:40:24.910
8589
48889
answer