まず、必要に応じて継承を難読化できることに注意してください。private
継承を使用してからvector
、withusing
ステートメントですべての機能を使用できるようにします。たくさんあるので、入力するのはまだかなりの量ですが、vector
すべての関数を明示的に委譲するほどではなく、継承に対する通常の反対意見を防ぎます.派生クラスを誤ってスライスしたり、仮想デストラクタがない場合の型が間違っています。とにかく誰かが削除するべきではありませvector
ん。
1)名前空間から同じ名前を使用することstd
は本質的に問題ではありませんが(結局のところ、それが名前空間の目的です)、読者を混乱させることがあります。using std::vector;
彼らはあなたがどこかでやったと思い込んでいるかもしれません。これは彼ら自身の責任ですが、別の適切な名前を思いつくことができれば、読者の間違いを罰しても何も得られません.
2) 標準クラスの演算子をオーバーロードできますが、std
名前空間ではできません。これにより、どのスコープでそれらをオーバーロードする必要があるかという疑問が残ります。通常、ヘッダー ファイルのグローバル スコープに何かを入れたくはありませんが、たとえば、名前空間と呼ばれる名前空間にそれらをvector_arithmetic
入れusing namespace vector_arithmetic;
てから、それぞれのスコープに入れることができます。それらを使用したいです。できるからといって、それが賢明であるとは限りません。読者は、 のような一般的なクラスで使用できる演算子を知っていることを期待していvector
ます。
3) C++11 コンストラクターの継承がない場合、コンストラクターを継承できません。代わりに、適切なパラメーターを受け取り、初期化子リストで適切な基本クラスのコンストラクターを呼び出す独自のコンストラクターを苦労して書き出す必要があります。標準 (またはその他のドキュメント) には、必要なすべてのコンストラクター シグネチャが記載されています。テンプレート化されたコンストラクターには特に注意してください。コンストラクターは C++03 と C++11 で同じではないことに注意してください。
最後に、いくつかのフリー関数を書くことを検討してください:
template <typename T>
T sequence_add(const T &lhs, const T &rhs) {
if (rhs.size() != lhs.size()) throw std::logic_error("size mismatch");
T result(lhs.size());
std::transform(lhs.begin(), lhs.end(), rhs.begin(), result.begin(),
std::plus<typename T::value_type>()
);
return result;
}
std::vector<int> i,j;
std::vector<int> k = sequence_add(i,j);
等々。演算子のオーバーロードが混乱を引き起こす場合は、一般的には価値がありません。