函数的静态变量返回引用

时间:2017-12-10 08:10:11

标签: c++ c++11 reference global-variables static-variables

我有一个类似地图的结构,当它无法在容器中找到元素时返回零。 由于访问是不可变的,因此返回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;
    }
};

0 个答案:

没有答案