2016-09-12 10 views
1

私のC++プレイグラウンドでコンテナで遊んでいて、むしろ技術的な問題に遭遇しました。テンプレートメンバー関数と引数転送

私はコンテナのemplaceメソッドを実装しようとしています。今のところそれは既に構築された要素をとり、それをアロケータ構築メソッドに渡すべきです。

私は3つの方法、テンプレートemplaceAおよびカップルemplaceB1,emplaceB2で終わった。すべて意図どおりに動作します。

私の問題はemplaceAで、Argは唯一T(これは私が欲しいものです)と明示的には述べていません。 emplaceB1の場合、emplaceB2は2つの異なる場所でほぼ同じ実装を提供します(私はそれを欠陥と見なします)。

回避策はありますか?

template<class T, class A> class container { 
public: 
    using allocator_traits = typename std::allocator_traits<A>; 
... 
    template<class Arg> void emplaceA (int n, Arg&& arg){ 
     allocator_traits::construct(allocator_, data_+n, std::forward<Arg>(arg));}; 

    void emplaceB1(int n, const T& t){ 
     allocator_traits::construct(allocator_, data_+n, t);}; 

    void emplaceB2(int n, T&& t){ 
     allocator_traits::construct(allocator_, data_+n, std::move(t));}; 
... 
}; 
+2

C++には関数のオーバーロードがあることは知っていますが、同じ名前で引数は異なる2つ(またはそれ以上)の関数を持つことができますか? –

+1

これは非常に奇妙なemplaceの実装です – SergeyA

+2

これは 'emplace'よりも' push_back'に似ています。これにより 'emplaceB1'と' emplaceB2'について気分が良くなるなら、['std :: vector :: push_back'](http://en.cppreference.com/w/cpp/container/vector/push_back)も来ます同じ2つの味で。 –

答えて

0

テンプレート化された関数を制限するには、sfinaeを使用して、不要な型の送信を防ぐことができます。

次の例では、ArgTに変換可能な場合のみ、テンプレート関数を呼び出し可能に制限しています。 is_convertibleは、2つのタイプが同じ場合でも機能します。

template<class Arg, std::enable_if_t<std::is_convertible<Arg, T>::value, int> = 0> 
void emplaceA(int n, Arg&& arg){ 
    // ... 
} 

がヘッダにもちろん<type_traits>


を含めることを忘れないでください、あなたが送っタイプは厳密にTであるかどうかを確認したい場合、あなたは減衰したタイプでstd::is_sameを使用することもできます。

template<class Arg, std::enable_if_t<std::is_same<std::decay_t<Arg>, T>::value, int> = 0> 
void emplaceA(int n, Arg&& arg){ 
    // ... 
} 
+0

ok、ありがとう。私はこのようなものを知らないので、それは素晴らしいですが、私はどこを見なければならないのかを知っています。答えの中の –

+0

@JiříLechner ' 'は良いドキュメントページへのリンクです。 ' – user4581301

関連する問題