C++的高级打印功能



有没有一种方法可以在C++中创建一个可以像Python一样使用的函数或宏?我的意思是像这样的函数

print(i); // i is an integer.
print(i, s); // i is an integer, s is a std::string. They are separated by a white space.

一个函数,它接收许多参数,然后只打印出它们,而不考虑它们的类型。

如果允许使用C++17,可以使用fold表达式,如下所示:

#include <iostream>
template<class ...Args>
void print(const Args &...args) {
auto seq_started = false;
auto print_impl = [&](auto &value) mutable {
if (seq_started) {
std::cout << " " << value;
} else {
seq_started = true;
std::cout << value;
}
};

(print_impl(args), ...);
}
int main() {
print("foo", 10, "bar", 20, "baz");
return 0;
}

使用流:

std::cout << i << ' ' << s << 'n';

对于更复杂的格式,请考虑fmt,它支持python的str.formatprintf样式格式的语法(但类型安全(。

我假设这个问题是关于一般解决方案的,print只是一个例子。

答案是:是的,使用重载和模板的组合。首先按类型设置功能:

void print_impl(const std::string& arg) {
std::cout << arg;
}
void print_impl(int arg) {
// Note: this is an example. Of course cout already
// does that for us with simple
//   std::cout << arg;
print_impl(convert_to_string(arg));
}
// cout already has lots of overloads, we can take
// advantage of that if needed:
template<class TArg>
void print_impl(TArg&& arg) {
std::cout << std::forward<TArg>(arg);
}

然后模板:

template<class TArg>
void print(TArg&& arg) {
print_impl(std::forward<TArg>(arg));
}
template<class TArg1, class ... TArgs>
void print(TArg1&& arg1, TArgs&& ... args) {
print_impl(std::forward<TArg1>(arg1));   // <-- print first argument
print_impl(" ");   // <-- insert separator, requires const std::string& overload
print(std::forward<TArgs>(args)...);   // <-- recursive call
}

在上面的代码中,如果需要,您可以将对print_impl的调用替换为直接对std::cout <<操作员的调用。虽然我会保留print_impl,因为它是std::cout之上的一个很好的层,以防将来你想替换它。

然后可以使用类似于Python:的方法

int main()
{
print("test");
print(1, 2, "foo");
print("foo", 1, 2);
return 0;
}

最新更新