Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

can't modify static set declared within a static method

I would like to store the value that is passed to the constructor in a static set returned by a static function.
It seems that the insertion is successful, but when it reach the end of the scope of the constructor it disappear.
I have reproduced it in a simple example:

// container.hh
#pragma once

#include <vector>
#include <set>

class container {
public:
    container(const int& s);
    static std::set<int, std::less<int>>& object_set_instance();
};

#include "container.hxx"
// container.hxx
#pragma once

#include "container.hh"

#include <iostream>


container::container(const int& s)
{
    auto set = object_set_instance();
    set.insert(s);
    std::cout << "Size " << set.size() << "\n";
}

std::set<int, std::less<int>>& container::object_set_instance()
{
    static std::set<int, std::less<int>> s;
    return s;
}
#include "container.hh"

#include <iostream>

int main()
{
    auto a = container(42);
    auto b = container(21);
    auto b1 = container(51);
    auto b2 = container(65);
    auto b3 = container(99);
}

Output :

Size 1
Size 1
Size 1 // Size never change
Size 1
Size 1

Why doesn’t the set’s size change ?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

   auto set = object_set_instance();

If you use your debugger to inspect what set is, you will discover that it’s a std::set and not a std::set& reference. Effectively, a copy of the original std::set is made (object_set_instance() returns a reference, only to copy-construct a new object that has nothing to do with the referenced one), and the next line of code modifies the copy, and it gets thrown away immediately afterwards.

This should be:

auto &set = object_set_instance();

A debugger is a very useful tool for solving these kinds of Scooby-Doo mysteries, and it would clearly reveal what’s going on here. If you haven’t yet had the opportunity to learn how to use one, hopefully this will inspire you to take a look, and join Mystery, Inc. as a member in good standing.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading