C++ 打印 vector 的几种方法小结

在 C++ 中,打印 vector 有多种方法,从简单到复杂,从手动实现到使用现代 C++ 特性。下面总结几种常用的方法:

图片[1]_C++ 打印 vector 的几种方法小结_知途无界

1. 基础循环方法

a. 传统 for 循环(下标访问)

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    for (size_t i = 0; i < vec.size(); i++) {
        cout << vec[i];
        if (i != vec.size() - 1) cout << " ";
    }
    cout << endl;
    
    return 0;
}

b. 范围-based for 循环(C++11)

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    for (const auto& element : vec) {
        cout << element << " ";
    }
    cout << endl;
    
    return 0;
}

c. while 循环(迭代器)

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    auto it = vec.begin();
    while (it != vec.end()) {
        cout << *it << " ";
        ++it;
    }
    cout << endl;
    
    return 0;
}

2. 使用 STL 算法

a. std::copy + std::ostream_iterator

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    
    return 0;
}

b. std::for_each + Lambda 表达式(C++11)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    for_each(vec.begin(), vec.end(), [](int element) {
        cout << element << " ";
    });
    cout << endl;
    
    return 0;
}

3. 重载输出运算符(推荐用于自定义类型)

a. 为特定类型 vector 重载

#include <iostream>
#include <vector>
using namespace std;

// 重载 << 运算符用于 vector<int>
ostream& operator<<(ostream& os, const vector<int>& vec) {
    os << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        os << vec[i];
        if (i != vec.size() - 1) os << ", ";
    }
    os << "]";
    return os;
}

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    cout << vec << endl;  // 输出: [1, 2, 3, 4, 5]
    
    return 0;
}

b. 模板版本(通用性好)

#include <iostream>
#include <vector>
#include <type_traits>
using namespace std;

// 模板重载 << 运算符用于任意类型 vector
template<typename T>
ostream& operator<<(ostream& os, const vector<T>& vec) {
    os << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        os << vec[i];
        if (i != vec.size() - 1) os << ", ";
    }
    os << "]";
    return os;
}

// 特化处理 string vector,避免引号
template<>
ostream& operator<<(ostream& os, const vector<string>& vec) {
    os << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        os << "\"" << vec[i] << "\"";
        if (i != vec.size() - 1) os << ", ";
    }
    os << "]";
    return os;
}

int main() {
    vector<int> intVec = {1, 2, 3, 4, 5};
    vector<string> strVec = {"hello", "world", "cpp"};
    
    cout << intVec << endl;   // 输出: [1, 2, 3, 4, 5]
    cout << strVec << endl;   // 输出: ["hello", "world", "cpp"]
    
    return 0;
}

4. 使用第三方库

a. 使用 fmt 库(现代 C++ 格式化库)

#include <iostream>
#include <vector>
#include <fmt/ranges.h>  // 需要安装 fmt 库
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    // 简单输出
    fmt::print("{}\n", vec);  // 输出: [1, 2, 3, 4, 5]
    
    // 自定义格式
    fmt::print("Vector: {}\n", fmt::join(vec, ", "));  // 输出: Vector: 1, 2, 3, 4, 5
    
    return 0;
}

b. 使用 Boost.Lambda(如果可用)

#include <iostream>
#include <vector>
#include <boost/lambda/lambda.hpp>
#include <boost/foreach.hpp>
using namespace std;
using namespace boost;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    BOOST_FOREACH(int element, vec) {
        cout << element << " ";
    }
    cout << endl;
    
    return 0;
}

5. 封装成函数模板

a. 简单的打印函数

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// 基础打印函数
template<typename T>
void printVector(const vector<T>& vec, const string& delimiter = " ") {
    for (size_t i = 0; i < vec.size(); ++i) {
        cout << vec[i];
        if (i != vec.size() - 1) cout << delimiter;
    }
    cout << endl;
}

// 带格式的打印函数
template<typename T>
void printVectorFormatted(const vector<T>& vec) {
    cout << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        cout << vec[i];
        if (i != vec.size() - 1) cout << ", ";
    }
    cout << "]" << endl;
}

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    printVector(vec);           // 输出: 1 2 3 4 5
    printVector(vec, ", ");     // 输出: 1, 2, 3, 4, 5
    printVectorFormatted(vec);  // 输出: [1, 2, 3, 4, 5]
    
    return 0;
}

b. 更高级的泛型打印函数

#include <iostream>
#include <vector>
#include <type_traits>
#include <string>
using namespace std;

template<typename T>
void advancedPrint(const vector<T>& vec, 
                  const string& left_bracket = "[",
                  const string& right_bracket = "]",
                  const string& delimiter = ", ") {
    
    cout << left_bracket;
    for (size_t i = 0; i < vec.size(); ++i) {
        cout << vec[i];
        if (i != vec.size() - 1) cout << delimiter;
    }
    cout << right_bracket << endl;
}

// 特化处理 bool 类型
template<>
void advancedPrint(const vector<bool>& vec, 
                  const string& left_bracket,
                  const string& right_bracket,
                  const string& delimiter) {
    
    cout << left_bracket;
    for (size_t i = 0; i < vec.size(); ++i) {
        cout << (vec[i] ? "true" : "false");
        if (i != vec.size() - 1) cout << delimiter;
    }
    cout << right_bracket << endl;
}

int main() {
    vector<int> intVec = {1, 2, 3, 4, 5};
    vector<bool> boolVec = {true, false, true};
    vector<string> strVec = {"a", "b", "c"};
    
    advancedPrint(intVec);                          // [1, 2, 3, 4, 5]
    advancedPrint(boolVec, "<", ">", "; ");         // <true; false; true>
    advancedPrint(strVec, "", "", " - ");           // "a" - "b" - "c"
    
    return 0;
}

6. C++23 新特性(std::print)

如果使用 C++23 或更高版本,可以使用新的 std::print 函数:

#include <iostream>
#include <vector>
#include <print>  // C++23
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};
    
    // C++23 的 std::print(如果编译器支持)
    // print("{}\n", vec);  // 输出格式取决于实现
    
    return 0;
}

方法比较与推荐

方法优点缺点适用场景
范围 for 循环简洁、易读、安全不能获取索引日常调试、简单遍历
​**重载 <<**​使用直观、可复用需要额外代码自定义类型、频繁使用
STL 算法函数式风格、简洁可读性稍差函数式编程风格
fmt 库现代、灵活、性能好需要第三方库现代 C++ 项目
封装函数灵活、可定制需要维护函数项目通用工具

最佳实践建议

  1. 日常调试​:使用范围-based for 循环
  2. 生产代码​:为常用类型重载 << 运算符
  3. 现代项目​:考虑使用 fmt 库
  4. 复杂需求​:封装通用的打印函数模板
  5. 性能敏感​:避免在循环中频繁调用 size(),可预先存储

选择哪种方法取决于具体需求、代码风格和个人偏好,但范围-based for 循环因其简洁性和安全性,通常是大多数情况下的首选。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞9 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容