我有一个类似地图的结构,当它无法在容器中找到元素时返回零。 由于访问是不可变的,因此返回const引用是有意义的, 在地图中找到元素和未找到元素的时候。
#include<map>
#include<cassert>
struct M{
std::map<int, double> vals;
double const& operator[](int i) const{
static double const zero = 0.0; // static variable in function
auto f = vals.find(i);
if(f == vals.end()) return zero;
return f->second;
}
};
int main(){
M m; m.vals = {{1, 11.}, {3, 33.}};
assert( m[2] == 11. );
assert( m[2] == 0. );
assert( m[3] == 33. );
}
但是我觉得将零值附加到对象上可能更好。
对于一个小内存(每个实例一个),我可以做零&#34;更多本地&#34;引用的对象(m
)。
struct M{
std::map<int, double> vals;
private:
double const zero = 0.0; // m
public:
double const& operator[](int i) const{
auto f = vals.find(i);
if(f == vals.end()) return zero;
return f->second;
}
};
哪个选项更好?在正确性和灵活性方面。
要考虑的事项(至少)是内存,线程和访问时间。
这让我想起了这个谈话,其中提议以这种方式重新实现std::string
终止字符&#39; \ 0&#39;是一个全局对象而不是每个字符串的部分内存。
https://www.youtube.com/watch?v=kPR8h4-qZdk
事实上,使用适当的修改后的复制构造函数,有一整套可能的实现(至少5个)在语义上是等价的:
static const double zero = 0.0; // free static variable
struct M{
std::map<int, double> vals;
double const& operator[](int i) const{
auto f = vals.find(i);
if(f == vals.end()) return zero;
return f->second;
}
};
static constexpr double zero = 0.0; // static constexpr
struct M{
std::map<int, double> vals;
double const& operator[](int i) const{
auto f = vals.find(i);
if(f == vals.end()) return zero;
return f->second;
}
};
struct M{
std::map<int, double> vals;
double const& operator[](int i) const{
static constexpr double zero = 0.0; // static constexpr in function
auto f = vals.find(i);
if(f == vals.end()) return zero;
return f->second;
}
};
struct M{
std::map<int, double> vals;
static constexpr double zero = 0.0; // static member constexpr
double const& operator[](int i) const{
auto f = vals.find(i);
if(f == vals.end()) return zero;
return f->second;
}
};
struct M{
std::map<int, double> vals;
static const double zero; // static const member
double const& operator[](int i) const{
auto f = vals.find(i);
if(f == vals.end()) return zero;
return f->second;
}
};
const double M::zero = 0.0;
最后,经过@StoryTeller的建议后,还有一个额外的选项可以按值返回:
struct M{
std::map<int, double> vals;
double operator[](int i) const{
auto f = vals.find(i);
if(f == vals.end()) return 0;
return f->second;
}
};