Is this legal to avoid set from creating actual copies of Comparator object

亡梦爱人 提交于 2019-12-07 05:42:29

问题


In such a code:

Comparator comp(3);

set<string, Comparator> s1(comp);
set<string, Comparator> s2(comp);
set<string, Comparator> s3(comp);
set<string, Comparator> s4(comp); 

the actual instance of the Comparator (namely comp) is copied at each creation of a set object as the cpp reference states

The container keeps an internal copy of alloc and comp, which are used to allocate storage and to sort the elements throughout its lifetime.

So we were wondering if this is legal in C++

#include <set>
#include <iostream>

struct A {
    int i = 0;
    bool operator()(int a, int b)
    {
        ++i;
        return a < b;
    }
};

int main()
{    
    A a;
    std::set<int, A&> s1( {1, 2, 3}, a);
    std::set<int, A&> s2( {4, 5, 6}, a);
    std::cout << a.i;
}

Thanks in advance.


回答1:


I'm unable to find wording in the standard forbidding using a reference type as the comparison function. Thus it seems that this would be legal. Note that some things, such as default constructing such a set, will be forbidden because your comparison type is not default constructable.

Finally note that the canonical C++ approach is to not do this, but to maintain the state externally. When you take that approach it's totally clear what you're doing and guaranteed to be safe:

#include <set>
#include <iostream>

struct A {
    int& i_;
    explicit A(int& state) : i_(state) { }
    bool operator()(int a, int b)
    {
        ++i_;
        return a < b;
    }
};

int main() {
    int i;
    std::set<int, A> s1( {1, 2, 3}, A(i));      
    std::set<int, A> s2( {4, 5, 6}, A(i));        
    std::cout << i << endl;
}


来源:https://stackoverflow.com/questions/22942686/is-this-legal-to-avoid-set-from-creating-actual-copies-of-comparator-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!