C++ C++;格式化宏/内联ostringstream
我正在尝试编写一个宏,它允许我执行以下操作:C++ C++;格式化宏/内联ostringstream,c++,format,printing,macros,ostringstream,C++,Format,Printing,Macros,Ostringstream,我正在尝试编写一个宏,它允许我执行以下操作:格式化(a您遇到的问题与操作符这是一个有效的解决方案: #define FORMAT(items) \ ((std::ostringstream&)(std::ostringstream() << std::dec << items)).str() #定义格式(项目)\ ((std::ostringstream&)
格式化(a您遇到的问题与操作符这是一个有效的解决方案:
#define FORMAT(items) \
((std::ostringstream&)(std::ostringstream() << std::dec << items)).str()
#定义格式(项目)\
((std::ostringstream&)(std::ostringstream()为什么不使用函数而不是宏?这里有一个像cadabra这样的答案,它不会影响ostream状态:
#define FORMAT(items) static_cast<std::ostringstream &>((std::ostringstream() << std::string() << items)).str()
#define FORMAT(items)static_cast((std::ostringstream()以下是我使用的内容。它完全适合头文件中一个整洁的类定义
更新:对代码的重大改进归功于
//makestring.h:
类生成字符串
{
公众:
std::stringstream;
运算符std::string()const{return stream.str();}
模板
MakeString&operator你们都已经很清楚这一点了。但要理解这一点有点挑战性。所以让我试着总结一下你们所说的
这里的困难在于:
- 我们正在玩一个临时的
ostringstream
对象,因此禁止使用地址
- 因为它是临时的,所以我们不能通过强制转换将其转换为
ostream
对象
- 构造函数[显然]和
str()
都是类ostringstream
方法。
(是的,我们需要使用.str()
。直接使用ostringstream
对象将调用ios::operator void*()
,返回一个指针,如good/bad value,而不是string对象。)
operator当我接受mrree的解决方案(标记为“首选”的解决方案,解释得很好的解决方案,以及适用于G++的解决方案)时,我遇到了MSVC++的问题:使用此宏生成的所有字符串最终都是空的
几个小时后(还有很多挠头和问问题),我发现seekp()调用是罪魁祸首。我不确定MSVC++与之有什么不同,但是
ostringstream().seekp( 0, ios_base::cur )
用卡达拉的
ostringstream() << std::dec
ostringstream(),因为他想使用插入运算符,所以假设我可以手动编写N个模板函数,每个参数一个,然后使用格式(a,“b”,c,d)。或者使用coppro的解决方案来生成它们。但两者都不好看。谢谢,这是非常有用的。我没有太多使用Boost,看看里面有什么很有趣。因为临时变量不能绑定到非常量引用。例如,string&str=string(“hello”);
无效。因此,char*
的重载无效(和许多其他重载)没有被选中。大卫:哈。原始海报特别提到了可变模板,这就是这个令人震惊的预处理器滥用所复制的(虽然不是一半)。别误会我的意思:你回答了问题的难点部分。没有在gcc 4.0.1上编译。这里有一个不会弄乱状态,但会复制字符串。\ define FORMAT(items)\((std::ostringstream&)(std::ostringstream()您的第二个示例将为您提供一个指向已销毁的临时字符串的指针-祝您好运。我尝试了该部分,但它仍然无法编译。我已将其从我的答案中删除!感谢您的输入。无需宏:放置模板StringMaker&operator@litb:那要优雅得多。谢谢!我有updated我的答案与Lynice的工作一致。请注意,如果字符串仅在表达式期间使用,则可以安全地隐式生成C样式的字符串。请参见dribeas在此处的密切相关工作:std::dec告诉流将数字呈现为基数10或十进制。它使用一个成员格式化程序,然后返回一个引用rence可以绑定到一个临时的。std::dec是一个很好的传递参数,它不会对流的输出产生副作用。
#define MAKE_OUTPUT(z, n, data) \
BOOST_PP_TUPLE_ELEM(2, 0, data) << BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n);
#define MAKE_FORMAT(z, n, data) \
template <BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(n), typename T)> \
inline string format(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(n), T, p)) \
{ \
ostringstream s; \
BOOST_PP_REPEAT_##z(z, n, MAKE_OUTPUT, (s, p)); \
return s.str(); \
}
#define FORMAT(items) \
((std::ostringstream&)(std::ostringstream() << std::dec << items)).str()
#define FORMAT(items) static_cast<std::ostringstream &>((std::ostringstream() << std::string() << items)).str()
// makestring.h:
class MakeString
{
public:
std::stringstream stream;
operator std::string() const { return stream.str(); }
template<class T>
MakeString& operator<<(T const& VAR) { stream << VAR; return *this; }
};
string myString = MakeString() << a << "b" << c << d;
#define FORMAT(ITEMS) \
( ( dynamic_cast<ostringstream &> ( \
ostringstream() . seekp( 0, ios_base::cur ) << ITEMS ) \
) . str() )
ostringstream().seekp( 0, ios_base::cur )
ostringstream() << std::dec