作为一个例子 - 假设我有接受三个整数参数的函数并想要创建一个日期 - 例如:
std::chrono<something> make_date(int year, int month, int day) {
...
}
这个 api 很危险,因为它很容易混合参数的顺序 - 即挪威人可能会喜欢称它为make_date(25, 12, 2021)圣诞节。我已经看到人们制作(零开销?)结构类型的模式,例如
struct Day ...
struct Month ...
struct Year ...
std::chrono<something> make_date(Year y, Month m, Day d) {
}
auto christmas_day = make_date(Year{2021}, Month{12}, Day{25});
但模式的细节让我望而却步。
更新:由于我的真实用例实际上根本与日期无关,我将制作一个更接近真实情况的替代示例。我有一个不可变的容器,global_size但容器中的许多元素都是空的 - 因此对应的非空元素的数量active_size远小于全局大小。容器中的元素非常大 - 所以只存储活动的:
template <typename T>
class container {
const T& get(std::size_t global_index) const {
auto active_index = this->index_map.at(global_index);
return this->storage[active_index];
}
private:
std::vector<T> storage;
std::map<std::size_t, std::size_t> index_map;
}
现在的重点是我想创建一个重载,它在空间中获取一个索引[0, active_size>并直接从存储中返回:
const T& get(std::size_t active_index) const {
return this->storage[active_index];
}
但由于该get(std::size_t) const插槽已被在空间[0, global_size>中采用索引的方法占用,该索引不是直接选项。这就是为什么我认为我可以制作简单的结构
struct ActiveIndex ...
struct GlobalIndex ...
本质上是美化std::size_t的——但仍然足以为重载解决方案提供基础。
更新 2:好的 - 事实证明这并没有我想象的那么神奇;
struct Day {
int value;
};
并访问内部 int 值,就像.value它的全部内容一样。