質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3502閲覧

クラステンプレートの部分特殊化でメンバ関数の再定義を省略したい

s8079

総合スコア36

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/12/15 11:20

編集2019/12/15 11:23

前提・実現したいこと

クラステンプレートの部分特殊化は非常に便利です.
しかし,部分特殊化するとすべてのメンバ関数を再定義しなければなりません.
可能であれば,再定義する必要のないメンバ関数は流用したいです.
良い解決方法があれば,教えてください.
よろしくお願いします.
ソースコードはテンプレートの特殊化 | Programming Place Plus C++編【言語解説】 第23章のものを書き換えました.

発生している問題・エラーメッセージ

error: 'class DataStore<int*>' has no member named 'PrintInit'

該当のソースコード

C++

1#include <iostream> 2 3template <typename T> 4class DataStore { 5private: 6 T mValue; 7 int init; 8public: 9 explicit DataStore(const T& value) : mValue(value), init(value) {} 10 void Print() const; 11 void PrintInit() const; 12}; 13 14template <typename T> 15void DataStore<T>::Print() const { 16 std::cout << mValue << std::endl; 17} 18 19template <typename T> 20void DataStore<T>::PrintInit() const { 21 std::cout << init << std::endl; 22} 23 24template <typename T> 25class DataStore<T*> { 26private: 27 T* mValue; 28 // int init; 29public: 30 explicit DataStore(T* value) : mValue(value) {} 31 void Print() const; 32 // void PrintInit() const; 33}; 34 35template <typename T> 36void DataStore<T*>::Print() const { 37 std::cout << *mValue << std::endl; 38} 39 40// template <typename T> 41// void DataStore<T*>::PrintInit() const { 42// std::cout << init << std::endl; 43// } 44 45int main() { 46 int num = 20; 47 DataStore<int> ds1(10); 48 DataStore<int*> ds2(&num); 49 ds1.Print(); 50 ds1.PrintInit(); 51 ds2.Print(); 52 ds2.PrintInit(); // error 53 return 0; 54}

補足情報(FW/ツールのバージョンなど)

C++11が望ましいですが,C++であればバージョンは限定しません.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

共通部をまとめて基底クラス化すれば良いと思います。

C++

1#include <iostream> 2 3class DataStoreCommon { 4private: 5 int init; 6public: 7 explicit DataStoreCommon(const int& value) : init(value) {} 8 void PrintInit() const { 9 std::cout << init << std::endl; 10 } 11}; 12 13template <typename T> 14class DataStore : public DataStoreCommon { 15private: 16 T mValue; 17public: 18 explicit DataStore(const T& value) : DataStoreCommon(value), mValue(value) {} 19 void Print() const; 20}; 21 22template <typename T> 23void DataStore<T>::Print() const { 24 std::cout << mValue << std::endl; 25} 26 27template <typename T> 28class DataStore<T*> : public DataStoreCommon { 29private: 30 T* mValue; 31 // int init; 32public: 33 explicit DataStore(T* value) : DataStoreCommon(*value), mValue(value) {} 34 void Print() const; 35 // void PrintInit() const; 36}; 37 38template <typename T> 39void DataStore<T*>::Print() const { 40 std::cout << *mValue << std::endl; 41} 42 43// template <typename T> 44// void DataStore<T*>::PrintInit() const { 45// std::cout << init << std::endl; 46// } 47 48int main() { 49 int num = 20; 50 DataStore<int> ds1(10); 51 DataStore<int*> ds2(&num); 52 ds1.Print(); 53 ds1.PrintInit(); 54 ds2.Print(); 55 ds2.PrintInit(); // error 56 return 0; 57}

wandbox

投稿2019/12/15 12:29

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2019/12/17 06:08 編集

やりたいことは実装詳細の共通化ですから、DataStoreCommonからはprivate継承としておき、派生先クラスでusing DataStoreCommon::PrintInit;とする方がより良いかも。
Chironian

2019/12/17 06:25

共通部分は抽象的な部分でもあるので、is_a関係は成立するケースが多いと思いますから、public継承でも問題はでにくいようにも感じます。 とはいえ、publicでまずい理由がある時にprivateを使うことを否定するものではないですが。
yohhoy

2019/12/17 06:29 編集

「DataStore<int>型やDataStore<char*>型をDataStoreCommon型に代入/変換できてよいか」という意味では、ほとんどのケースでプログラマの期待に反する動作とは思います。 いいかえると、ここでのクラス間関係は is-a ではないというのが私の解釈です。 この辺りは、どのくらいプログラマの誤りを未然に検知したいか/予防的プログラミングに向けた設計という考え方次第ですね。
Chironian

2019/12/17 06:43

なるほど。 スライシングを回避出来るので、共通部を抽象クラスとして使わないのであれば、private継承の方が良さそうですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問