2016-12-30 10 views
-1

std::setのマルチプレックスを作成しました。これはNDos::set_multiplexという名前で、さまざまな比較オブジェクトの視点から要素を表示できます。例えば、トランプのセットはランク1とスーツ2、またはスーツ1とランク2で並べ替えることができます。 NDos::set_multiplexはこれを便利に行うことができます。 NDos::set_multiplexは、複数の要素を格納している複数の要素と要素にイテレータを格納している要素を継承しています。 NDos::IterCompは、2つのイテレータが参照する要素を比較するタイプのCallableです。パラメータパックの展開が機能しない

/*...*/ 
namespace NDos { 
    template <class T, class Comp0, class... Comps> class set_multiplex : 
     private std::set<T, Comp0>, 
     private std::set< 
      typename std::set<T, Comp0>::iterator, 
      IterComp<typename std::set<T, Comp0>::iterator, Comps> 
     >... { 
    private: 
     typedef std::set<T, Comp0> Base0; 
    public: 
     /*...*/ 
     using typename Base0::iterator; 
     using typename Base0::const_iterator; 
     using typename Base0::reverse_iterator; 
     using typename Base0::const_reverse_iterator; 
#define Bases std::set<iterator, IterComp<iterator, Comps>> 
     /*constructors*/ 
     // copy constructor : default 
     // move constructor : default 
     // copy assignment operator : default 
     // move assignment operator : default 
     // destructor : default 
     /*...*/ 
     void clear() noexcept { 
      Base0::clear(); 
      Bases::clear()...; 
     } 
     iterator insert(const T &value) { 
      return emplace(value); 
     } 
     iterator insert(T &&value) { 
      return emplace(std::move(value)); 
     } 
     iterator insert(const_iterator pos, const T &value) { 
      return emplace_hint(pos, value); 
     } 
     iterator insert(const_iterator pos, T &&value) { 
      return emplace_hint(pos, std::move(value)); 
     } 
     template <class InputIt> void insert(InputIt first, InputIt last) { 
      while (first != last) 
       insert(*first++); 
     } 
     void insert(std::initializer_list<T> ilist) { 
      insert(std::make_move_iterator(ilist.begin()), std::make_move_iterator(ilist.end())); 
     } 
     template <class... Args> iterator emplace(Args &&...args) { 
      iterator i0 = Base0::emplace(std::forward<Args>(args)...).first; 
      Bases::insert(i0)...; 
      return i0; 
     } 
     template <class... Args> iterator emplace_hint(const_iterator pos, Args &&...args) { 
      iterator i0 = Base0::emplace_hint(pos, std::forward<Args>(args)...).first; 
      Bases::insert(i0)...; 
      return i0; 
     } 
     iterator erase(iterator pos) { 
      Bases::erase(pos)...; 
      return Base0::erase(pos); 
     } 
     iterator erase(const_iterator first, const_iterator last) { 
      while (first != last) 
       erase(first++); 
     } 
     size_type erase(const T &key) { 
      iterator pos = find(key); 
      if (pos == end()) 
       return 0; 
      else { 
       erase(pos); 
       return 1; 
      } 
     } 
     void swap(set_multiplex &other) noexcept { 
      Base0::swap(other); 
      Bases::swap(other)...; 
     } 
     /*...*/ 
#undef Bases 
    }; 
} 

パラメータパックが適切に展開されていません。ここで

はコードです。 G ++ 6.2レポートこれらのエラー各拡張:(機能clearemplaceemplace_hinterase、およびswapで)

error: expected ';' before '...' token 
error: parameter packs not expanded with '...' 

は、なぜこれらが起こるのか? C++ 11では

+0

より完全なコンパイル出力を投稿してください。どこかに行番号があります(そして、どの行になっているかを表示します)。また、コードを重要な部分に減らそうとします。 – Christoph

+0

@Christophはい、しました。 –

答えて

2

は、単にこれを行うことはできません。

Bases::insert(i0)...; 
Bases::erase(pos)...; 
Bases::swap(other)...; 

しよう:同じはあなたがそのように...を使用している他のすべての場所のために起こる

Bases::clear()...; 

void clear() noexcept { 
    Base0::clear(); 
    int _[] = { 0, (Bases::clear(), 0)... }; 
    (void)_; // silent warnings, nothing more 
} 

これは、C++ 17を待っている間に使用される一般的なトリックです。その折り畳み式。


swap機能について特に言及:あなたはBase0otherを交換する場合、otherは、理論的には、スワップ後Base0内のデータが含まれています。それをもう一度別のスワップに使うのは良い考えではないようです。
swap機能の実装を確認する必要があります。

+0

'Base0 :: swap(other)'の間、要素はコピーも移動もされず、すべてのイテレータは有効なままです。これは問題ありません。 –

関連する問題