gpt4 book ai didi

c++ - 为 std::vector 键入安全索引值

转载 作者:行者123 更新时间:2023-11-28 04:45:11 25 4
gpt4 key购买 nike

我有一些类从不同的常量 STL vector 中收集索引值。问题是,即使这些 vector 的内容不同并且用途不同,它们的索引也是 std::size_t 类型,因此可能会错误地使用为一个 vector 存储的索引来访问元素另一个 vector 。当索引未与正确的 vector 一起使用时,是否可以更改代码以产生编译时错误?

代码示例:

#include <iostream>
#include <string>
#include <vector>

struct Named
{
std::string name;
};

struct Cat : Named { };
struct Dog : Named { };

struct Range
{
std::size_t start;
std::size_t end;
};

struct AnimalHouse
{
std::vector< Cat > cats;
std::vector< Dog > dogs;
};

int main( )
{
AnimalHouse house;
Range cat_with_name_starting_with_a;
Range dogs_with_name_starting_with_b;

// ...some initialization code here...

for( auto i = cat_with_name_starting_with_a.start;
i < cat_with_name_starting_with_a.end;
++i )
{
std::cout << house.cats[ i ].name << std::endl;
}

for( auto i = dogs_with_name_starting_with_b.start;
i < dogs_with_name_starting_with_b.end;
++i )
{
// bad copy paste but no compilation error
std::cout << house.cats[ i ].name << std::endl;
}

return 0;
}

免责声明:请不要过分关注示例本身,我知道它很愚蠢,只是为了理解这个想法。

最佳答案

这是对我的评论的跟进尝试。
当然,根据用例,有很大的空间可以更改其工作方式的细节,这种方式对我来说似乎是合理的。

#include <iostream>
#include <vector>

template <typename T>
struct Range {
Range(T& vec, std::size_t start, std::size_t end) :
m_vector(vec),
m_start(start),
m_end(end),
m_size(end-start+1) {}

auto begin() {
auto it = m_vector.begin();
std::advance(it, m_start);
return it;
}
auto end() {
auto it = m_vector.begin();
std::advance(it, m_end + 1);
return it;
}

std::size_t size() {
return m_size;
}

void update(std::size_t start, std::size_t end) {
m_start = start;
m_end = end;
m_size = end - start + 1;
}

Range copy(T& other_vec) {
return Range(other_vec, m_start, m_end);
}

typename T::reference operator[](std::size_t index) {
return m_vector[m_start + index];
}

private:
T& m_vector;
std::size_t m_start, m_end, m_size;
};

// This can be used if c++17 is not supported, to avoid
// having to specify template parameters
template <typename T>
Range<T> make_range(T& t, std::size_t start, std::size_t end) {
return Range<T>(t, start, end);
}

int main() {
std::vector<int> v1 {1, 2, 3, 4, 5};
std::vector<double> v2 {0.5, 1., 1.5, 2., 2.5};

Range more_then_2(v1, 1, 4); // Only works in c++17 or later
auto more_then_1 = make_range(v2, 2, 4);

for (auto v : more_then_2)
std::cout << v << ' ';

std::cout << std::endl;

for (auto v : more_then_1)
std::cout << v << ' ';

std::cout << std::endl;

more_then_2.update(2,4);

for (auto v : more_then_2)
std::cout << v << ' ';

std::cout << std::endl;

auto v3 = v1;
auto more_then_2_copy = more_then_2.copy(v3);

for (unsigned i=0; i < more_then_2_copy.size(); ++i)
std::cout << more_then_2_copy[i] << ' ';

return 0;
}

关于c++ - 为 std::vector 键入安全索引值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49387406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com