0

C#スタイルで印刷する必要があるタスクを作成しました

tprintf("{} world{} {} {} {}\n","こんにちは",'!',123,"ジェ", "終わり");

そして、コードは以下です

void tprintf(const char* format) // base function
{
    std::cout << format;
}

template<typename T, typename... Targs>
void tprintf(const char* format, T value, Targs... Fargs)
{
    for ( ; *format != '\0'; format++ ) {
           if(*format == '{'){
                if(format[1] == '}'){
           std::cout << value;
           tprintf(format+2, Fargs...); // recursive call
           return;
           }
        }
        std::cout << *format;
    }
}

ここで、少し違うものを作成する必要があります。

tprintf("{1} {3} + {2} = {4} {1}.", "11", 7.5 , 4, 11.5);

出力:

11 4 + 7.5 = 11.5 11.

したがって、ここでは、引数に対する単純な再帰反復は機能しないと思います。機能するすべての引数を知る必要があります。最初にすべての引数を配列に取得してから、パターン文字列の正しい場所に入力する必要があると思います。しかし、どのように?

私はこれを作りました

template<typename... Args> inline string pass(Args&&...) {return "End";}

template<typename T>
string some_function(T a){
    std::ostringstream ostr;
    ostr << a;
    //cout<<ostr.str();
    return ostr.str();
}

  template<typename... Args> inline void expand(Args&&... args) {
    string a="";
        
    a.append(pass( some_function(args)... ))<<endl;

    cout<<" result "<<a<<endl;
  }

struct pass {
    template<typename ...T> pass(T...) {}
  };

ただし、これは「End」のみを返します。この動作の原因は、テンプレートの動作と再帰に関連していることに気付きました。再帰で呼び出される最後の考えは template<typename... Args> inline string pass(Args&&...) {return "End";} なので、関数を展開します 解析されたすべての引数を含む文字列ではなく、 End 文字列のみを取得します文字列。

だから私の質問は、この機能をうまく機能させる方法です

tprintf("{1} {3} + {2} = {4} {1}.", "", 7.5 , 4, 11.5);
4

2 に答える 2

0

ラムダ関数を使用する場合があります。

template< typename ... args >
void tprintf( char const * fmt, args const & ... a ) {
    std::array< std::function< void() >, sizeof ... (a) > fmt_fun
        = { [&a]{ std::cout << a; } ... };

    for ( ; * fmt; ++ fmt ) {
        ...
        std::size_t fmt_n = * fmt - '0';
        fmt_fun[ fmt_n ](); // print nth argument
        ...
    }
}

メタプログラミング スタイルの再帰的なパックの反復は必要ないことに注意してください。

うーん、このコードは Clang では機能しますが、GCC では長年のバグに違反します。

于 2013-06-08T11:11:21.113 に答える
0

最終的に次のようなものが得られます。

a.append(pass("7.5"), pass("4"), pass("11.5"))

aに「End」を追加します。

まず第一に、明らかに、実際に配列を指定しても、cout はここで「配列」を受け入れません。そして、パラメータを1つずつ出力する必要があります。したがって、再帰によってすべてを抽出する必要があります。

于 2013-06-08T09:40:32.810 に答える