前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ vector 使用详解(含C++20新特性)

C++ vector 使用详解(含C++20新特性)

作者头像
用户7886150
修改2021-01-19 10:20:20
1.6K0
修改2021-01-19 10:20:20
举报
文章被收录于专栏:bit哲学院bit哲学院bit哲学院

参考链接: C++ Vector元素改变时Iterator失效

目录 

介绍两个关键词 

元素访问 

迭代器 

容量 

修改操作 

emplace() & emplace_back() 

std::erase & std::erase_if (std::vector) 

简介 

C++ 的 vector 本质上是一个动态数组,它的元素是连续存储的,这意味着不仅可以通过迭代器访问元素,还可以使用指向元素的常规指针来对其进行访问。还可以将指向 vector 元素的指针传递给任何需要指向数组元素的指针的函数。 

vector 的存储是自动处理的,可以根据需要进行扩展和收缩。vector 通常比静态数组占用更多的空间,因为分配了更多的内存来处理将来的增长。这样,vector 不必在每次插入元素时都重新分配,而仅在附加内存耗尽时才需要重新分配。可以使用 capacity() 函数查询已分配的内存总量。可以通过调用 shrink_to_fit() 将额外的内存返回给系统。 

就性能而言,重新分配空间通常是费时的操作。如果元素的数目是预先已知的,调用 reserve() 函数可以消除重新分配。 

介绍两个关键词 

(1) constexpr 是 C++11 中新增的关键字,其语义是 "常量表达式",也就是在编译期可求值的表达式。最基础的常量表达式就是字面值或全局变量/函数的地址或 sizeof 等关键字返回的结果,而其它常量表达式都是由基础表达式通过各种确定的运算得到的。 constexpr 值可用于 enum、switch、数组长度等场合。 

constexpr 所修饰的变量一定是编译期可求值的,所修饰的函数在其所有参数都是 constexpr 时,一定会返回 constexpr。 

constexpr int Inc(int i) {

    return i + 1;

}

constexpr int a = Inc(1);         // ok

constexpr int b = Inc(cin.get()); // error!

constexpr int c = a * 2 + 1;      // ok 

constexpr 的好处: 

 (1) 是一种很强的约束,更好地保证程序的正确语义不被破坏。 

 (2) 编译器可以在编译期对 constexpr 的代码进行非常大的优化,比如将用到的 constexpr 表达式都直接替换成最终结果等。 

 (3) 相比宏来说,没有额外的开销,但更安全可靠。 

(2) noexcept 关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。如果在运行时,noexecpt 函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用 std::terminate() 函数,该函数内部会调用 std::abort() 终止程序。 

元素访问 

at 通过边界检查访问指定的元素 

reference       at( size_type pos );

const_reference at( size_type pos ) const; 

返回对指定位置的元素的引用 pos,并进行边界检查。如果 pos 不在容器范围内,则会引发类型为 std::out_of_range 的异常。 

operation[ ] 用于访问指定的元素 

reference       operator[]( size_type pos );

const_reference operator[]( size_type pos ) const; 

返回对指定位置的元素的引用 pos。不执行边界检查。表明我们可以像使用数组一样使用 vector。 

#include <vector>

#include <iostream>

int main()

{

    std::vector<int> numbers {2, 4, 6, 8};

    std::cout << "Second element: " << numbers[1] << '\n';

    numbers[0] = 5;

    std::cout << "All numbers:";

    for (auto i : numbers) {

        std::cout << ' ' << i;

    }

    std::cout << '\n';

front 用于访问第一个元素 

reference front();

const_reference front() const; 

返回对容器中第一个元素的引用,未定义 front 在空容器上的调用。 

back 用于访问最后一个元素 

reference back();

const_reference back() const; 

返回对容器中最后一个元素的引用,空容器调用 back 会导致未定义的行为。 

#include <vector>

#include <iostream>

int main()

{

    std::vector<char> letters {'o', 'm', 'g', 'w', 't', 'f'};

    if (!letters.empty()) {

        std::cout << "The first character is: " << letters.front() << '\n';

        std::cout << "The last character is: " << letters.back() << '\n';

    }  

data 用于直接访问基础数组 

constexpr T* data() noexcept;                      (since C++20)

constexpr const T* data() const noexcept;          (since C++20) 

返回值:指向基础元素存储的指针。对于非空容器,返回的指针等于第一个元素的地址。如果 size() 为0,则 data() 可能会或可能不会返回空指针。 

迭代器 

begin() & cbegin() 

iterator begin() noexcept;

const_iterator begin() const noexcept;

const_iterator cbegin() const noexcept; 

返回指向 vector 的第一个元素的迭代器。如果的 vector 值为空,则返回的迭代器将等于 end()。 

end() & cend() 

iterator end() noexcept;

const_iterator end() const noexcept;

const_iterator cend() const noexcept; 

返回指向 vector 的最后一个元素之后的迭代器。begin、end 与 cbegin、cend的区别是后者是指向常量的指针,在使用的过程中不允许改变指向内容的值。此元素充当占位符;尝试访问它会导致未定义的行为。 

#include <iostream>

#include <vector>

#include <string>

int main()

{

    std::vector<int> ints {1, 2, 4, 8, 16};

    std::vector<std::string> fruits {"orange", "apple", "raspberry"};

    std::vector<char> empty;

    // Sums all integers in the vector ints (if any), printing only the result.

    int sum = 0;

    for (auto it = ints.cbegin(); it != ints.cend(); it++)

        sum += *it;

    std::cout << "Sum of ints: " << sum << "\n";

    // Prints the first fruit in the vector fruits, without checking if there is one.

    std::cout << "First fruit: " << *fruits.begin() << "\n";

    if (empty.begin() == empty.end())

        std::cout << "vector 'empty' is indeed empty.\n";

}

输出:

Sum of ints: 31

First fruit: orange

vector 'empty' is indeed empty. 

rbegin() & crbegin() 

reverse_iterator rbegin() noexcept;

const_reverse_iterator rbegin() const noexcept;

const_reverse_iterator crbegin() const noexcept; 

将反向迭代器返回给 reversed 的第一个元素 vector。它对应于 non-reversed 的最后一个元素 vector。如果向量为空,则返回的迭代器等于 rend()。 

rend() & crend() 

reverse_iterator rend() noexcept;

const_reverse_iterator rend() const noexcept;

const_reverse_iterator crend() const noexcept; 

返回反向迭代器,该迭代器返回 reversed 的最后一个元素之后的元素 vector。它对应于 non-reversed 的第一个元素之前的元素 vector。该元素充当占位符,尝试访问它会导致未定义的行为。 

容量 

empty() 检查容器有没有元素,即是否 begin () == end ()。 

constexpr bool empty() const noexcept; 

#include <vector>

#include <iostream>

int main()

{

    std::cout << std::boolalpha;

    std::vector<int> numbers;

    std::cout << "Initially, numbers.empty(): " << numbers.empty() << '\n';

    numbers.push_back(42);

    std::cout << "After adding elements, numbers.empty(): " << numbers.empty() << '\n';

}

输出:

Initially, numbers.empty(): true

After adding elements, numbers.empty(): false 

size() 返回容器中元素的数量,即 std::distance( begin (), end ())。 

size_type size() const noexcept; 

#include <vector>

#include <iostream>

int main()

    std::vector<int> nums {1, 3, 5, 7};

    std::cout << "nums contains " << nums.size() << " elements.\n";

}

输出:

nums contains 4 elements. 

max_size()返回由于系统或库实现限制,容器可以容纳的最大元素数。 

size_type max_size() const noexcept; 

#include <iostream>

#include <vector>

int main()

{

    std::vector<char> s;

    std::cout << "Maximum size of a 'vector' is " << s.max_size() << "\n";

}

输出:

Maximum size of a 'vector' is 9223372036854775807s 

reserve() 将 vector 的容量增加到大于或等于的值 new_cap。 

void reserve( size_type new_cap ); 

如果 new_cap 大于当前的 capacity(),则分配新的存储,否则该方法不执行任何操作。reserve() 不会更改 vector 的元素个数,如果 new_cap 大于 capacity(),则所有迭代器(包括过去的迭代器)以及对元素的所有引用都将无效。否则,没有迭代器或引用无效。 

#include <cstddef>

#include <new>

#include <vector>

#include <iostream>

// minimal C++11 allocator with debug output

template <class Tp>

struct NAlloc {

    typedef Tp value_type;

    NAlloc() = default;

    template <class T> NAlloc(const NAlloc<T>&) {}

    Tp* allocate(std::size_t n)

    {

        n *= sizeof(Tp);

        std::cout << "allocating " << n << " bytes\n";

        return static_cast<Tp*>(::operator new(n));

    }

    void deallocate(Tp* p, std::size_t n) 

    {

        std::cout << "deallocating " << n*sizeof*p << " bytes\n";

        ::operator delete(p);

    }

};

template <class T, class U>

bool operator==(const NAlloc<T>&, const NAlloc<U>&) { return true; }

template <class T, class U>

bool operator!=(const NAlloc<T>&, const NAlloc<U>&) { return false; }

int main()

{

    int sz = 100;

    std::cout << "using reserve: \n";

    {

        std::vector<int, NAlloc<int>> v1;

        v1.reserve(sz);

        for(int n = 0; n < sz; ++n)

            v1.push_back(n);

    }

    std::cout << "not using reserve: \n";

    {

        std::vector<int, NAlloc<int>> v1;

        for(int n = 0; n < sz; ++n)

            v1.push_back(n);

    }

}

输出:

using reserve: 

allocating 400 bytes

deallocating 400 bytes

not using reserve: 

allocating 4 bytes

allocating 8 bytes

deallocating 4 bytes

allocating 16 bytes

deallocating 8 bytes

allocating 32 bytes

deallocating 16 bytes

allocating 64 bytes

deallocating 32 bytes

allocating 128 bytes

deallocating 64 bytes

allocating 256 bytes

deallocating 128 bytes

allocating 512 bytes

deallocating 256 bytes

deallocating 512 bytes

capacity() 返回容器当前已分配空间的元素的个数。 

size_type capacity() const noexcept; 

shrink_to_fit() 请求删除未使用的容量,将 capacity() 减小为 size()。 

void shrink_to_fit();    (since C++11) 

如果发生重新分配,则所有迭代器(包括过去的结束迭代器)以及对元素的所有引用都将无效。如果没有发生重新分配,则没有迭代器或引用无效。 

#include <iostream>

#include <vector>

int main()

{

    std::vector<int> v;

    std::cout << "Default-constructed capacity is " << v.capacity() << '\n';

    v.resize(100);

    std::cout << "Capacity of a 100-element vector is " << v.capacity() << '\n';

    v.clear();

    std::cout << "Capacity after clear() is " << v.capacity() << '\n';

    v.shrink_to_fit();

    std::cout << "Capacity after shrink_to_fit() is " << v.capacity() << '\n';

}

输出:

Default-constructed capacity is 0

Capacity of a 100-element vector is 100

Capacity after clear() is 100

Capacity after shrink_to_fit() is 0 

修改操作 

clear() 清除元素 

void clear() noexcept; 

clear 清除容器中的所有元素,调用之后,size() 返回零。使所有引用包含元素的引用,指针或迭代器无效。 

insert() 插入元素 

(1)iterator insert( const_iterator pos, const T& value );

(2)iterator insert( const_iterator pos, T&& value );

(3)iterator insert( const_iterator pos, size_type count, const T& value );

(4)template< class InputIt >

   iterator insert( const_iterator pos, InputIt first, InputIt last );

(5)iterator insert( const_iterator pos, std::initializer_list<T> ilist ); 

 (1-2) value 在之前插入 pos。 

 (3) 插入 count 个 value 副本到 pos 之前 。 

 (4) 将 [first, last) 范围内的元素插入 pos 之前。 

 (5) 将 ilist 插入 pos 之前。 

如果新的 size() 大于旧的 capacity(),则导致重新分配。如果新的 size() 大于 capacity(),则所有迭代器和引用均无效。否则,只有插入点之前的迭代器和引用保持有效。 

#include <iostream>

#include <vector>

void print_vec(const std::vector<int>& vec)

{

    for (auto x: vec) {

         std::cout << ' ' << x;

    }

    std::cout << '\n';

}

int main ()

{

    std::vector<int> vec(3,100);

    print_vec(vec);

    auto it = vec.begin();

    it = vec.insert(it, 200);

    print_vec(vec);

    vec.insert(it,2,300);

    print_vec(vec);

    // "it" no longer valid, get a new one:

    it = vec.begin();

    std::vector<int> vec2(2,400);

    vec.insert(it+2, vec2.begin(), vec2.end());

    print_vec(vec);

    int arr[] = { 501,502,503 };

    vec.insert(vec.begin(), arr, arr+3);

    print_vec(vec);

}

输出:

100 100 100

200 100 100 100

300 300 200 100 100 100

300 300 400 400 200 100 100 100

501 502 503 300 300 400 400 200 100 100 100 

erase() 从容器中删除指定的元素 

iterator erase( const_iterator pos );

iterator erase( const_iterator first, const_iterator last ); 

 (1) 删除处的元素 pos。 

 (2) 删除范围内的元素 [first, last)。 

在删除点或删除点之后使迭代器和引用无效,包括 end() 迭代器。迭代器 pos 必须有效且可取消引用。因此,end() 迭代器(有效,但不可取消引用)不能用作的值 pos。first 如果满足以下条件,则不需要取消迭代器 first==last:删除空范围是无操作的。 

#include <vector>

#include <iostream>

int main( )

{

    std::vector<int> c{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    for (auto &i : c) {

        std::cout << i << " ";

    }

    std::cout << '\n';

    c.erase(c.begin());

    for (auto &i : c) {

        std::cout << i << " ";

    }

    std::cout << '\n';

    c.erase(c.begin()+2, c.begin()+5);

    for (auto &i : c) {

        std::cout << i << " ";

    }

    std::cout << '\n';

    // Erase all even numbers (C++11 and later)

    for (auto it = c.begin(); it != c.end(); ) {

        if (*it % 2 == 0) {

            it = c.erase(it);

        } else {

            ++it;

        }

    }

    for (auto &i : c) {

        std::cout << i << " ";

    }

    std::cout << '\n';

}

输出:

0 1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

1 2 6 7 8 9

1 7 9 

push_back() 将给定元素添加到容器末尾 

void push_back( const T& value );   (1)

void push_back( T&& value );        (2) 

 (1) 使用 value 的副本初始化新元素。 

 (2) value被移到新元素中。 

如果新的 size() 大于 capacity(),则所有迭代器和引用(包括过去的迭代器)都将失效。否则,只有过去的迭代器是无效的。由于隐式调用了 reserve(size()+ 1) 的等效项,某些实现还会导致重新分配超过最大的 size 时引发 std::length_error。 

#include <vector>

#include <iostream>

#include <iomanip>

int main()

{

    std::vector<std::string> numbers;

    numbers.push_back("abc");

    std::string s = "def";

    numbers.push_back(std::move(s));

    std::cout << "vector holds: ";

    for (auto&& i : numbers) std::cout << std::quoted(i) << ' ';

    std::cout << "\nMoved-from string holds " << std::quoted(s) << '\n';

}

输出:

vector holds: "abc" "def" 

Moved-from string holds "" 

pop_back() 删除容器的最后一个元素 

void pop_back(); 

删除容器的最后一个元素,pop_back 未定义在空容器上的调用。迭代器对最后一个元素的引用以及 end() 迭代器均无效。 

#include <vector>

#include <iostream>

template<typename T>

void print(T const & xs)

{

    std::cout << "[ ";

    for(auto const & x : xs) {

        std::cout << x << ' ';

    }

    std::cout << "]\n";

}

int main()

{

    std::vector<int> numbers;

    print(numbers); 

    numbers.push_back(5);

    numbers.push_back(3);

    numbers.push_back(4);

    print(numbers); 

    numbers.pop_back();

    print(numbers); 

}

输出:

[ ]

[ 5 3 4 ]

[ 5 3 ] 

resize() 调整容器 

void resize( size_type count );                                (1)

void resize( size_type count, const value_type& value );       (2) 

调整容器的大小以包含 count 元素。如果当前大小大于 count,则容器将缩小为其第一个 count 元素。如果当前大小小于 count,需要附加额外的拷贝值 value。在将大小调整为更小时,vector 容量不会减少,因为这将使所有迭代器失效,而是等效于调用 pop_back() 导致迭代器失效的情况。   

#include <iostream>

#include <vector>

int main()

{

    std::vector<int> c = {1, 2, 3};

    std::cout << "The vector holds: ";

    for(auto& el: c) std::cout << el << ' ';

    std::cout << '\n';

    c.resize(5);

    std::cout << "After resize up to 5: ";

    for(auto& el: c) std::cout << el << ' ';

    std::cout << '\n';

    c.resize(2);

    std::cout << "After resize down to 2: ";

    for(auto& el: c) std::cout << el << ' ';

    std::cout << '\n';

}

输出:

The vector holds: 1 2 3

After resize up to 5: 1 2 3 0 0

After resize down to 2: 1 2 

swap() 交换容器 

void swap( vector& other ) noexcept;       (since C++17) 

与 other 容器完成交换。不对单个元素调用任何移动,复制或交换操作。 

#include <vector>

#include <iostream>

void printVector(std::vector<int>& vec)

{

    for (int a : vec)

    {

        std::cout << a << " ";

    }

}

int main()

{

    std::vector<int> v1{1, 2, 3};

    std::vector<int> v2{7, 8, 9};

    std::cout << "v1: ";

    printVector(v1);

    std::cout << "\nv2: ";

    printVector(v2);

    std::cout << "\n-- SWAP\n";

    v2.swap(v1);

    std::cout << "v1: ";

    printVector(v1);

    std::cout << "\nv2: ";

    printVector(v2);

}

输出:

v1: 1 2 3

v2: 7 8 9

-- SWAP

v1: 7 8 9

v2: 1 2 3 

emplace() & emplace_back() 

C++11 新标准引入了三个新成员:emplace_front、emplace 和 emplace_back,这些操作构造而不是拷贝元素。这些操作分别对应 push_front、insert 和 push_back,允许将元素放置在容器头部、一个指定位置之前或容器尾部。 

当调用 push 或 insert 成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中。而当我们调用一个 emplace 成员函数时,则是将参数传递给元素类型的构造函数。emplace 成员使用这些参数在容器管理的内存空间中直接构造元素。 

emplace 函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。emplace 函数在容器中直接构造元素。传递给 emplace 函数的参数必须与元素类型的构造函数相匹配。 

emplace()  

template< class... Args > 

iterator emplace( const_iterator pos, Args&&... args );    (since C++11) 

将新元素直接插入容器的 pos 之前。元素是通过 std::allocator_traits::construct 构造的,通常使用 placement-new 在容器提供的位置就地构造元素。参数 args... 作为 std::forward < Args > ( args ) ... 转发给构造函数。如果新的 size() 大于 capacity(),则所有迭代器和引用均无效。否则,只有插入点之前的迭代器和引用保持有效。 

emplace_back() 

template< class... Args >

reference emplace_back( Args&&... args );            (since C++17) 

将新元素附加到容器的末尾。该元素是通过 std::allocator_traits::construct 构造的,通常使用 placement-new 在容器提供的位置就地构造该元素。参数 args... 作为 std::forward < Args > ( args ) ... 转发给构造函数。如果新的 size() 大于 capacity(),则所有迭代器和引用(包括过去的迭代器)都将失效。否则,只有过去的迭代器是无效的。   

处理基础数据类型: 

// reference: http://www.cplusplus.com/reference/vector/vector/emplace_back/

int test()

{

    {   /*

           template <class... Args>

           void emplace_back (Args&&... args);

         */

        std::vector<int> myvector = { 10, 20, 30 };

        myvector.emplace_back(100);

        myvector.emplace_back(200);

        std::cout << "myvector contains:";

        for (auto& x : myvector)

            std::cout << ' ' << x;

        std::cout << '\n';

    }

    {   /*

           template <class... Args>

           iterator emplace (const_iterator position, Args&&... args);

         */

        std::vector<int> myvector = { 10, 20, 30 };

        auto it = myvector.emplace(myvector.begin() + 1, 100);

        myvector.emplace(it, 200);

        myvector.emplace(myvector.end(), 300);

        std::cout << "myvector contains:";

        for (auto& x : myvector)

            std::cout << ' ' << x;

        std::cout << '\n';

    }

    return 0;

处理对象: 

#include <vector>

#include <string>

#include <iostream>

struct President

{

    std::string name;

    std::string country;

    int year;

    President(std::string p_name, std::string p_country, int p_year)

        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)

    {

        std::cout << "I am being constructed.\n";

    }

    President(President&& other)

        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)

    {

        std::cout << "I am being moved.\n";

    }

    President& operator=(const President& other) = default;

};

int main()

{

    std::vector<President> elections;

    std::cout << "emplace_back:\n";

    elections.emplace_back("Nelson Mandela", "South Africa", 1994);

    std::vector<President> reElections;

    std::cout << "\npush_back:\n";

    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));

    std::cout << "\nContents:\n";

    for (President const& president: elections) {

        std::cout << president.name << " was elected president of "

                  << president.country << " in " << president.year << ".\n";

    }

    for (President const& president: reElections) {

        std::cout << president.name << " was re-elected president of "

                  << president.country << " in " << president.year << ".\n";

    }

}

输出:

emplace_back:

I am being constructed.

push_back:

I am being constructed.

I am being moved.

Contents:

Nelson Mandela was elected president of South Africa in 1994.

Franklin Delano Roosevelt was re-elected president of the USA in 1936. 

emplace_back() 与 push_back() 对比: 

// reference: https://corecplusplustutorial.com/difference-between-emplace_back-and-push_back-function/

class Dat {

    int i;

    std::string ss;

    char c;

    public:

    Dat(int ii, std::string s, char cc) :i(ii), ss(s), c(cc) { }

    ~Dat() { }

};

int test_emplace_4()

{

    std::vector<Dat> vec;

    vec.reserve(3);

    vec.push_back(Dat(89, "New", 'G')); // efficiency lesser

    //vec.push_back(678, "Newer", 'O'); // error,push_back can’t accept three arguments

    vec.emplace_back(890, "Newest", 'D'); // work fine, efficiency is also more

    return 0;

std::erase & std::erase_if (std::vector) 

template< class T, class Alloc, class U >

constexpr typename std::vector<T,Alloc>::size_type

    erase(std::vector<T,Alloc>& c, const U& value);      (1) (since C++20)

template< class T, class Alloc, class Pred >

constexpr typename std::vector<T,Alloc>::size_type

    erase_if(std::vector<T,Alloc>& c, Pred pred);        (2) (since C++20) 

(1) 从容器中删除所有等于 value 的元素。相当于: 

auto it = std::remove(c.begin(), c.end(), value);

auto r = std::distance(it, c.end());

c.erase(it, c.end());

return r; 

(2) pred 从容器中擦除所有满足谓词的元素。相当于: 

auto it = std::remove_if(c.begin(), c.end(), pred);

auto r = std::distance(it, c.end());

c.erase(it, c.end());

return r; 

#include <iostream>

#include <numeric>

#include <vector>

void print_container(const std::vector<char>& c)

{

    for (auto x : c) {

        std::cout << x << ' ';

    }

    std::cout << '\n';

}

int main()

{

    std::vector<char> cnt(10);

    std::iota(cnt.begin(), cnt.end(), '0');

    std::cout << "Init:\n";

    print_container(cnt);

    std::erase(cnt, '3');

    std::cout << "Erase \'3\':\n";

    print_container(cnt);

    auto erased = std::erase_if(cnt, [](char x) { return (x - '0') % 2 == 0; });

    std::cout << "Erase all even numbers:\n";

    print_container(cnt);

    std::cout << "In all " << erased << " even numbers were erased.\n";

}

输出:

Init:

0 1 2 3 4 5 6 7 8 9 

Erase '3':

0 1 2 4 5 6 7 8 9 

Erase all even numbers:

1 3 7 9

In all 5 even numbers were erased.

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档