C++ 中的打印函数类似于 Python

Print function in C++ similar to Python

提问人:Zohaib Hamdule 提问时间:12/29/2022 最后编辑:kiner_shahZohaib Hamdule 更新时间:11/15/2023 访问量:411

问:

我正在尝试制作一个头文件,使其易于学习 C++。 我想知道是否有任何方法可以在 C++ 中制作一个打印函数,其行为类似于 Python 中的打印函数,无论传递给它的数据的数据类型或维度如何,它都会打印数据。

我可以制作一个函数,可以使用模板和函数重载打印任何数字类型和字符串。但我正在为向量和数组而苦苦挣扎,因为它们可能是多维的。

我可以使用这个让它打印多达 3D 矢量:

#include <iostream>
#include <vector>

template<typename T>
void printVector(const std::vector<T>& vec)
{
    for (const auto& element : vec)
        std::cout << element << ' ';
    std::cout << '\n';
}

template<typename T>
void printVector(const std::vector<std::vector<T>>& vec)
{
    for (const auto& innerVector : vec)
        printVector(innerVector);
}

int main()
{
    std::vector<int> vec1{ 1, 2, 3, 4, 5 };
    std::vector<std::vector<double>> vec2{ { 1.1, 2.2 }, { 3.3, 4.4 } };
    std::vector<std::vector<std::vector<char>>> vec3{ { { 'a', 'b' }, { 'c', 'd' } }, { { 'e', 'f' }, { 'g', 'h' } } };

    printVector(vec1);
    printVector(vec2);
    printVector(vec3);

    return 0;
}
C++ 模板 泛型

评论

3赞 tkausl 12/29/2022
你太想这个矢量打印例程了。有一个函数,它只使用每个元素调用自己。如果它是另一个向量,好吧,它只是递归。如果不是,也没问题,它会选择另一个重载。printvector<T>
2赞 Ted Lyngmo 12/29/2022
std::format 使它的外观和感觉非常像 python。std::cout << std::format("Hello {}!\n", "world");
2赞 HolyBlackCat 12/29/2022
在 C++ 23 中。我不认为使用自己的标题进行教学是一个好主意,以后必须忘记。std::print
2赞 Ted Lyngmo 12/29/2022
{fmt} 在 C++17 中工作 - 它是合并到 C++20 中的独立库(只是它比 C++20 中包含的内容要多得多,例如着色等)。
1赞 wohlstad 12/29/2022
“我可以让它打印多达 3D 矢量”——您在使用较暗的矢量时遇到什么问题(似乎它应该可以工作)?

答:

2赞 sklott 12/29/2022 #1

你可以做这样的事情:

#include <iostream>
#include <vector>
#include <map>

namespace detail {
    template<typename T>
    void printImpl(const T& o)
    {
        std::cout << o;
    }

    template<typename T>
    void printImpl(const std::vector<T>& vec)
    {
        char sep = '{';
        for (const auto& innerVector : vec) {
            std::cout << sep;
            printImpl(innerVector);
            sep = ',';
        }
        std::cout << "}";
    }

    template<typename K, typename V>
    void printImpl(const std::map<K, V>& cont)
    {
        char sep = '{';
        for (auto&& [k, v] : cont) {
            std::cout << sep;
            printImpl(k);
            std::cout << ":";
            printImpl(v);
            sep = ',';
        }
        std::cout << "}";
    }
}

template<typename... Args>
void print(Args&&... args)
{
    (detail::printImpl(std::forward<Args>(args)), ...);
}

int main()
{
    std::vector<int> vec1{ 1, 2, 3, 4, 5 };
    std::vector<std::vector<double>> vec2{ { 1.1, 2.2 }, { 3.3, 4.4 } };
    std::vector<std::vector<std::vector<char>>> vec3{ { { 'a', 'b' }, { 'c', 'd' } }, { { 'e', 'f' }, { 'g', 'h' } } };
    std::map<int, std::string> m{{0, "a"},{1, "b"}};

    print(vec1,"\n");
    print(vec2,"\n");
    print(vec3,"\n");
    print(m,"\n");

    return 0;
}

并专门针对您不喜欢默认行为的任何类型。detail::printImpl()operator <<()

评论

0赞 Zohaib Hamdule 12/29/2022
它也可以与地图一起使用吗?
1赞 sklott 12/29/2022
答案是肯定的。编辑以添加地图。
2赞 HolyBlackCat 12/29/2022
列出单个容器不是最好的主意。可能应该有一个模板,该模板可以接受任何看起来像容器的内容。
1赞 sklott 12/29/2022
@HolyBlackCat 可能是的,但是如果没有概念(OP问C++17版本),对于OP来说可能太复杂了。
1赞 Ryota Sasaki 11/15/2023 #2

我做了这样的事情: 我做了一个 C++ 版本的 Python print() 函数 您可以通过简单地将变量传递给函数
,以类似 Python 的字符串表示形式打印各种变量。
这不仅包括嵌套向量,还包括元组和许多其他类型。
这是一个仅标头库,适用于 C++ 17 或更高版本。