C++ 的高级打印函数

Toà*_*yễn 2 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.
Run Code Online (Sandbox Code Playgroud)

一个接受多个参数的函数,然后不管类型如何都将它们打印出来。

Obj*_*ect 7

使用流:

std::cout << i << ' ' << s << '\n';
Run Code Online (Sandbox Code Playgroud)

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


fre*_*ish 6

我认为这个问题是关于一般解决方案的,这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);
}
Run Code Online (Sandbox Code Playgroud)

然后模板:

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
}
Run Code Online (Sandbox Code Playgroud)

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

然后你可以像 Python 一样使用它:

int main()
{
    print("test");
    print(1, 2, "foo");
    print("foo", 1, 2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Dee*_*doo 6

如果允许使用 C++17,则可以使用 fold-expression 来完成,如下所示:

#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;
}
Run Code Online (Sandbox Code Playgroud)