std :: ostream&operator <<連結オブジェクトのリストを唯一の引数として取り、統合された文字列を単一のstd::stringオブジェクトとして関数に渡すマクロを作成したいと思います。統合された文字列を関数に渡す機能が重要です。以下の例では、マクロをに定義するだけで例自体が機能するように書き直すことができることを認識していますERR_MSG(inputs) std::cout << "ERROR: " << inputs
が、出力をstd :: coutに送信することは目標ではなく、例として選択したテストの目的にすぎません。
GCC 4.1.2(Red Hat 4.1.2-52)を使用していますが、アップグレードすることはできません。これが私が試したものの非常に要約されたバージョンです:
#include <sstream>
#include <iostream>
#define ERR_MSG(inputs) errMsg(std::ostringstream().str()) // 1
#define ERR_MSG(inputs) errMsg((std::ostringstream()<<inputs).str()) // 2
<aReturnType> errMsg(const std::string& msg) // use with 1 & 2
{
std::cout << "\nERROR: " << msg << "\n\n";
return <someObjectCreatedBasedOnTheInput>;
}
#define ERR_MSG(inputs) errMsg(std::ostringstream()<<inputs) // 3
<aReturnType> errMsg(const std::ostringstream& msg) // use with 3
{
std::cout << "\nERROR: " << msg.str() << "\n\n";
return <someObjectCreatedBasedOnTheInput>;
}
int main()
{
ERR_MSG("A number: " << 24 << ", a char: " << 'c' << ", that's all!");
}
マクロ#1はコンパイルされますが、もちろんメッセージには「」しか出力されません。マクロ2と3はどちらもコンパイルされず、次のエラーが発生します。
#define ERR_MSG(inputs) errMsg((std::ostringstream()<<inputs).str()) // 2
error: ‘struct std::basic_ostream<char, std::char_traits<char> >’ has no member named ‘str’
#define ERR_MSG(inputs) errMsg(std::ostringstream()<<inputs) // 3
no matching function for call to ‘errMsg(std::basic_ostream<char, std::char_traits<char> >&)’
note: candidates are: char* errMsg(const std::string&)
note: char* errMsg(const std::ostringstream&)
マクロなしでこれを書き直す方法には興味がありません。自分でも簡単にできます。
===更新:===実際のユースケースでは、マクロによって呼び出された関数が、マクロの呼び出し元によって使用される可能性のあるオブジェクトを返すことを忘れました。これにより、単一の式で実装できないマクロ実装が無効になり、その結果、マクロによって呼び出された関数の戻り型が無効になります。マクロの「何もしない」実装(リリースビルドの場合)は、「入力」が何であるかに関係なく、空のstd::stringを関数に渡すだけです。先に言及しなかったことをお詫びします。