2016-10-18 17 views
0

私はこのような機能の束書いている:簡素化作業

template <> 
Error SyntaxError<unfinished_string>(unsigned int line) { 
    std::stringstream message; 
    message << "SyntaxError: unfinished string (starting at line " << line << ")."; 
    return Error(Error::Type::syntax, message.str()); 
} 

template <> 
Error SyntaxError<malformed_number>(std::string number, unsigned int line) { 
    std::stringstream message; 
    message << "SyntaxError: malformed number (" << number << ") at line " << line << '.'; 
    return Error(Error::Type::Syntax, message.str()); 
} 

... 

をそして、このような何かを見可変引数関数/マクロを持つことが悪いではないでしょう。

Error proto(/*variable number & type of arguments*/) { 
    std::stringstream message; 
    message << "SyntaxError: " << /*arguments passed, separated by <<s */; 
    return Error(Error::Type::syntax, message.str()); 
} 

私はその後、私のような機能を記述することができるように:

template <> 
Error SyntaxError<unfinished_string>(unsigned int line) { 
    return proto("unfinished string (starting at line ", line, ")."); 
} 

template <> 
Error SyntaxError<malformed_number>(std::string number, unsigned int line) { 
    return proto("malformed number (", number, ") at line ", line, '.'); 
} 

が可能万が一ということですか?どうすればいいですか?

+0

なぜ人々が投票を締結したのかよく分かりません。答えは「はい」です。本当の答えを一秒でまとめるつもりです。 – xaxxon

+0

いくつのバージョンが必要ですか? 'Error'にコンストラクタを追加できますか? ['std :: system_error'](http://en.cppreference.com/w/cpp/error/system_error/system_error)と同様です。 –

答えて

1

可変引数のリストを変換してそれらを完全にストリーミングする場合は、各引数をそのストリームに再帰的に追加する追加の関数を実装できます。 例:

template< typename FirstArg, typename... Args > 
inline std::ostream& join_args(std::ostream& os, FirstArg arg, Args... args) { 
    os << arg; 
    return join_args(os, args...); 
} 

ステップバイステップ、あなたは引数を排出されます。あなたが処理する注文に注意してください。(std::ostream& os, FirstArg arg, Args... args)(std::ostream& os, Args... args, LastArg arg)と同じではありません。

なく、少なくとも最後に、あなたは(あなたの問題に応じて、1つまたは引数なしのいずれか)のコーナーケースをカバーする必要があります

inline std::ostream& join_args(std::ostream& os) { 
    return os; 
} 

は再帰効率を心配しないで、コンパイラがインライン化することができるようになりますすべての関数呼び出し(コンパイル時に再帰の深さを知る)とすべてのコードを平坦化するので、結果のプログラムはすべての引数を手動で単一のストリームに追加することと多かれ少なかれ同等になります。

+1

'return join_args(args ...);'最初の引数として 'os'を渡してはいけません(つまり、' join_args(os、args ...) ')? – user6245072

+0

それは魅力のように動作します!どうもありがとうございます! – user6245072

+0

間違いなくuser6245072、私はちょうどそれをコード化し、それらの誤りを見直すのを忘れました。ありがとう! –