将 C++ 宏重写为函数等
Rewriting a c++ macro as a function, etc
我有一个经常使用的宏,灵感来自另一个问题:
#define to_string(x) dynamic_cast<ostringstream &> (( ostringstream() << setprecision(4) << dec << x )).str()
这个非常方便,例如与接受字符串输入的函数一起使用:
some_function(to_string("The int is " << my_int));
然而,有人告诉我在 C++ 中使用宏是一种不好的做法,事实上我在让上述内容在不同的编译器上工作时遇到了问题。有没有办法把它写成另一种结构,例如一个功能,哪里会有同样的通用性?
在 C++11 及更高版本中,我们现在有 std::to_string
。我们可以使用它将数据转换为字符串并将其附加到您想要的任何内容。
some_function("The int is " + std::to_string(my_int));
具有讽刺意味的是,to_string
正是您想要的。
而不是:to_string("The int is " << my_int)
你可以这样写:"The int is " + to_string(my_int)
这将 return 一个 string
。
您的宏比 std::to_string
提供的可能性更多。它接受任何合理的 <<
运算符序列,设置默认精度和十进制基数。一种兼容的方法是创建一个 std::ostringstream
包装器,它可以隐式转换为 std::string
:
class Stringify {
public:
Stringify() : s() { s << std::setprecision(4) << std::dec; };
template<class T>
Stringify& operator<<(T t) { s << t; return *this; }
operator std::string() { return s.str(); }
private:
std::ostringstream s;
};
void foo(std::string s) {
std::cout << s << std::endl;
}
int main()
{
foo(Stringify() << "This is " << 2 << " and " << 3 << " and we can even use manipulators: " << std::setprecision(2) << 3.1234);
}
我有一个经常使用的宏,灵感来自另一个问题:
#define to_string(x) dynamic_cast<ostringstream &> (( ostringstream() << setprecision(4) << dec << x )).str()
这个非常方便,例如与接受字符串输入的函数一起使用:
some_function(to_string("The int is " << my_int));
然而,有人告诉我在 C++ 中使用宏是一种不好的做法,事实上我在让上述内容在不同的编译器上工作时遇到了问题。有没有办法把它写成另一种结构,例如一个功能,哪里会有同样的通用性?
在 C++11 及更高版本中,我们现在有 std::to_string
。我们可以使用它将数据转换为字符串并将其附加到您想要的任何内容。
some_function("The int is " + std::to_string(my_int));
具有讽刺意味的是,to_string
正是您想要的。
而不是:to_string("The int is " << my_int)
你可以这样写:"The int is " + to_string(my_int)
这将 return 一个 string
。
您的宏比 std::to_string
提供的可能性更多。它接受任何合理的 <<
运算符序列,设置默认精度和十进制基数。一种兼容的方法是创建一个 std::ostringstream
包装器,它可以隐式转换为 std::string
:
class Stringify {
public:
Stringify() : s() { s << std::setprecision(4) << std::dec; };
template<class T>
Stringify& operator<<(T t) { s << t; return *this; }
operator std::string() { return s.str(); }
private:
std::ostringstream s;
};
void foo(std::string s) {
std::cout << s << std::endl;
}
int main()
{
foo(Stringify() << "This is " << 2 << " and " << 3 << " and we can even use manipulators: " << std::setprecision(2) << 3.1234);
}