title: I've used a proxy in my operator[] to implicitly convert a boost::variant. How can I maintain assignment through operator[]?
body: <p>I'm writing a configuration file parser that reads a configuration file with format <code>key: value</code> into an <code>std::map&lt;string, ConfigVariant</code> with <code>ConfigVariant</code> defined as <code>typedef boost::variant&lt;double, long int, std::string&gt; ConfigVariant;</code></p>
  
  <p>Here are the important parts of my config class:</p>
  
  <pre><code>typedef boost::variant&lt;double, long int, std::string&gt; ConfigVariant;
  
  class Config {
  private:
    std::map&lt;std::string, ConfigVariant&gt; config_values;
  
    // This struct is important
    struct Proxy {
    public:
      template&lt;typename T&gt; T as() { return boost::get&lt;T&gt;(data); }
      template&lt;typename T&gt; operator T() { return as&lt;T&gt;(); }
  
    private:
      ConfigVariant data;
  
      Proxy(ConfigVariant data) { this-&gt;data = data; }
      Proxy(const Proxy &amp;other);
      Proxy &amp; operator=(const Proxy &amp;other);
      friend class Config;
    };
  
  public:
    Config(std::string config_file_name);
    Proxy operator[] (const std::string &amp;key); // Important
  };
  </code></pre>
  
  <p>The only relevant implementation is that of <code>operator[]</code> which looks like this:</p>
  
  <pre><code>Config::Proxy Config::operator[] (const string &amp;key) {
    return Proxy(config_values[key]);
  }
  </code></pre>
  
  <p>This code allows me to have something like this:</p>
  
  <pre><code>// config_file
  double_key: 4.2
  
  // driver.cpp
  int main() {
    Config config("path/to/config_file");
  
    double d = config["double_key"] // Look ma, no cast
    d += 1
  
    cout &lt;&lt; d &lt;&lt; endl; // Prints 5.2
  
    return 0;
  }
  </code></pre>
  
  <p>I am happy with this behavior, but as you can see, I cannot return a reference from <code>operator[]</code>. Because I am not returning a reference, I cannot perform assignment through <code>operator[]</code>. This is somewhat of a problem because I would like to modify the configuration values after loading them from a hash. I would also like to keep the <code>config["key"]</code> syntax. Any ideas?</p>
  
  <p>EDIT:</p>
  
  <p>I've changing Proxy to store <code>ConfigVariant *</code> and then tried overloading <code>operator=</code>. Here is exactly what I've tried:</p>
  
  <pre><code>Proxy &amp; operator=(ConfigVariant &amp;other) { *data = other; return *this; }
  </code></pre>
  
  <p>This gave me the following error:</p>
  
  <pre><code>app/driver.cpp: In function ‘int main()’:
  app/driver.cpp:11: error: no match for ‘operator=’ in ‘Config::operator[](const std::string&amp;)(((const std::string&amp;)(&amp; std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;(((const char*)"key3"), ((const std::allocator&lt;char&gt;&amp;)((const std::allocator&lt;char&gt;*)(&amp; std::allocator&lt;char&gt;()))))))) = 5.20000000000000017763568394002504646778106689453125e+0’
  app/../config/config.hpp:37: note: candidates are: Config::Proxy&amp; Config::Proxy::operator=(const Config::Proxy&amp;)
  app/../config/config.hpp:44: note:                 Config::Proxy&amp; Config::Proxy::operator=(ConfigVariant&amp;)
  </code></pre>
  
  <p>Then I tried:</p>
  
  <pre><code>ConfigVariant &amp; operator=(ConfigVariant &amp;other) { *data = other; return *data; }
  </code></pre>
  
  <p>Which gave me pretty much the same error:</p>
  
  <pre><code>app/driver.cpp: In function ‘int main()’:
  app/driver.cpp:11: error: no match for ‘operator=’ in ‘Config::operator[](const std::string&amp;)(((const std::string&amp;)(&amp; std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;(((const char*)"key3"), ((const std::allocator&lt;char&gt;&amp;)((const std::allocator&lt;char&gt;*)(&amp; std::allocator&lt;char&gt;()))))))) = 5.20000000000000017763568394002504646778106689453125e+0’
  app/../config/config.hpp:37: note: candidates are: Config::Proxy&amp; Config::Proxy::operator=(const Config::Proxy&amp;)
  app/../config/config.hpp:44: note:                 ConfigVariant&amp; Config::Proxy::operator=(ConfigVariant&amp;)
  </code></pre>