Note that there are some explanatory texts on larger screens.

plurals
  1. POsubscript operators for class with std::map member variable
    primarykey
    data
    text
    <p>I am trying to make a class that wraps std::map and does checking to make sure the keys are one the of approved valid strings, and also initializes the map to have default values for all the approved valid strings. I am having issues getting the subscript operator to work, specifically the const version of it.</p> <p>Here is my class prototyping code:</p> <pre><code>#include &lt;set&gt; #include &lt;string&gt; #include &lt;map&gt; class foo { public: foo() {} const double &amp; operator[](const std::string key) const { return data[key]; } private: static const std::set&lt;std::string&gt; validkeys; std::map&lt;std::string, double&gt; data; }; const std::set&lt;std::string&gt; foo::validkeys = {"foo1", "foo2"}; </code></pre> <p>When I compile this (using g++ with -std=c++0x), I get this compilation error:</p> <pre><code>|| /home/luke/tmp/testmap.cc: In member function 'double&amp; foo::operator[](std::string) const': testmap.cc|10 col 22 error| passing 'const std::map&lt;std::basic_string&lt;char&gt;, double&gt;' as 'this' argument of 'mapped_type&amp; std::map&lt;_Key, _Tp, _Compare, _Alloc&gt;::operator[](const key_type&amp;) [with _Key = std::basic_string&lt;char&gt;, _Tp = double, _Compare = std::less&lt;std::basic_string&lt;char&gt; &gt;, _Alloc = std::allocator&lt;std::pair&lt;const std::basic_string&lt;char&gt;, double&gt; &gt;, mapped_type = double, key_type = std::basic_string&lt;char&gt;]' discards qualifiers </code></pre> <p>Nothing I do seems to fix this. I have tried</p> <ul> <li>making validkeys a std::set and data std::map</li> <li>using const char * instead of string</li> <li>returning const double or double instead of const double &amp;</li> <li>using list and vector instead of set to store the validkeys</li> </ul> <p>I don't know if I'm even approaching this problem correctly so if there is some other simple way to create a class that allows this kind of functionality:</p> <pre><code>foo a; a["foo2"] = a["foo1"] = 5.0; // This would raise a std::runtime_error because I would be checking that // "foo3" isn't in validkeys a["foo3"] = 4.0; </code></pre> <p>Any suggestions greatly appreciated.</p> <p><strong>SOLUTION</strong></p> <p>The following works exactly how I want it to, I even have a basic exception when you try to set or get a key that isn't in the set of valid keys:</p> <pre><code>#include &lt;iostream&gt; #include &lt;string&gt; #include &lt;map&gt; #include &lt;set&gt; #include &lt;stdexcept&gt; class myfooexception : public std::runtime_error { public: myfooexception(const std::string &amp; s) : std::runtime_error(s + " is not a valid key.") {} }; class foo { public: foo() { for (std::set&lt;std::string&gt;::iterator it = validkeys.begin(); it != validkeys.end(); ++it) { data[*it] = 0.0; } } const double &amp; operator[](const std::string &amp; key) const { if (data.find(key) == data.end()) { throw myfooexception(key); } else { return data.find(key)-&gt;second; } } double &amp; operator[](const std::string &amp; key) { if (data.find(key) == data.end()) { throw myfooexception(key); } else { return data[key]; } } private: static const std::set&lt;std::string&gt; validkeys; std::map&lt;std::string, double&gt; data; }; const std::set&lt;std::string&gt; foo::validkeys = {"foo1", "foo2"}; int main(void) { foo a; a["foo1"] = 2.0; a["foo1"] = a["foo2"] = 1.5; // a["foo3"] = 2.3; // raises exception: foo3 is is not a valid key const foo b; std::cout &lt;&lt; b["foo1"]; // should be ok // b["foo1"] = 5.0; // compliation error, as expected: b is const. return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload