2017-05-06 7 views
3

私は http://www.cplusplus.com/reference/vector/vector/vector/を参照しているベクトルコンテナを実装しようとしています。私はvector<int> vec(100, 1);を使用する場合ベクトルコンストラクタのインスタンス化の競合

template <typename T> 
vector (size_type n, const T& val); 

template <typename T> 
template <typename InputIterator> 
vector (InputIterator first, InputIterator last); 

:いくつかの問題を引き起こして2つのコンストラクタがあります。両方のテンプレートコンストラクタがインスタンス化を行うようです。だから私はtemplate <typename T> vector (size_type n, const T& val)を持っています。T = inttemplate <typename T> template <typename InputIterator> vector (InputIterator first, InputIterator last)T = int、InputIterator = intです。

どうすれば解決できますか?

+3

"両方のテンプレートコンストラクタをインスタンス化する"とはどういう意味ですか? –

+0

また、競合がどのように見えますか?どのようなエラーメッセージが表示されますか? C++ 11より前の[mcve] – UnholySheep

答えて

4

標準(C++ 11以来)では、引数がイテレータとして機能するときにオーバーレイされたconstructor of std::vectorがパラメータとしてイテレータを受け取るだけで、オーバーロード解決に参加する必要があることに注意してください。

InputIt満たしInputIterator場合、このオーバーロードは、過負荷(2)とのあいまいさを回避するために、オーバーロード解決に関与します。

SFINAEstd::iterator_traitsを使用して、独自のベクターの実装を実現できます。例えばInputIterator = intの場合には

template <typename InputIterator, typename = typename std::iterator_traits<InputIterator>::value_type> 
vector (InputIterator first, InputIterator last) { ... } 

std::iterator_traits<int>は、過負荷がオーバーロードの解決の外に支配され、 value_typeのような任意のメンバーの種類が含まれていません。


BTW:より正確には、問題は「両方のテンプレートコンストラクタをインスタンス化する」ではありません。あなたの実装でsize_typeの正確なタイプがわからない場合、intのようにstd::size_tの場合、vector<int> vec(100, 1);の場合、1番目の引数をintからstd::size_tに変換する必要があるため、 2番目のオーバーロードはInputIterator = intとの完全一致のインスタンス生成を生成する可能性があるため選択されます。それは私たちが期待する行動ではありません。

+0

...と標準は、引数が整数型であれば、 'vector(InputIter、InputIter)'は他のオーバーロードと同じように動作する必要がありました。 – aschepler