ムラサメ研究ブログ

主にゲームやプログラミングのログ

右辺値参照~完全転送まで100%理解するぞ! part8 おまけ。

おまけ

可変引数テンプレートの Parameter Bagを展開しながら 全部出力する

#include<iostream>

using namespace std;



struct Concat{
    template <class... T>
    void operator ()(T&&... t) {
        concat_(std::forward<T>(t)...);
    }
private:
    void concat_() {
    }

    template <class Head, class... Tail>
    void concat_(Head&& head, Tail&&... tail)
    {
        cout << head;
        concat_(std::forward<Tail>(tail)...);
    }
    
};

auto main() -> int
{ 
  Concat con;
  con("test int:", 1 );
  
  return 1;
}

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

上記のように template void concat(Head&& head, Tail&&… tail) とParmeterBagを 先頭1個とその他に分割し concat(std::forward(t)…); と、後半部分だけ渡して を繰り返すと全部展開できる 注意するのは ParameterBagは 0個以上なので 0個の場合もあるので、ラストは void concat_() だ。

今はcoutに出力しているが 当然 operator << を実装したくなる

#include<iostream>
#include<sstream>

using namespace std;



struct Concat{
    template <class... T>
    Concat& operator ()(T&&... t) {
        concat_(std::forward<T>(t)...);
        return *this;
    }
    
    friend ostream& operator << (ostream &os,  Concat& obj);
private:
    stringstream ss_;
    
    void concat_() {
    }

    template <class Head, class... Tail>
    void concat_(Head&& head, Tail&&... tail)
    {
        ss_ << head;
        concat_(std::forward<Tail>(tail)...);
    }    
};

    inline ostream& operator << (ostream &os,  Concat& obj){
        os << obj.ss_.str();
        obj.ss_.str("");
        return os;
    }


auto main() -> int
{ 
  Concat con;
  cout << con("test int:", 1 ) << endl;
  
  return 1;
}

operator() で thisを返し operator << にて streamへ。

最期に 再帰の部分をフリー関数へ(私の好み)

#include<iostream>
#include<sstream>

using namespace std;

ostream& concat_( ostream &ss_) {
  return ss_;
}

template <class Head, class... Tail>
    ostream& concat_(ostream &ss_, Head&& head, Tail&&... tail)
{
    ss_ << head;
    return concat_(ss_, std::forward<Tail>(tail)...);
}    


struct Concat{
    template <class... T>
    Concat& operator ()(T&&... t) {
        concat_(ss_, std::forward<T>(t)...);
        return *this;
    }
    
    friend ostream& operator << (ostream &os,  Concat& obj);
private:
    stringstream ss_;
};

    inline ostream& operator << (ostream &os,  Concat& obj){
        os << obj.ss_.str();
        obj.ss_.str("");
        return os;
    }


auto main() -> int
{ 
  Concat con;
  cout << con("test int:", 1 ) << endl;
  
  return 1;
}

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ