title: Prevent function taking const std::string& from accepting 0
body: <p>Worth a thousand words:</p>
  <pre><code>#include&lt;string&gt;
  #include&lt;iostream&gt;
  
  class SayWhat {
      public:
      SayWhat&amp; operator[](const std::string&amp; s) {
          std::cout &lt;&lt; s &lt;&lt; &quot;\n&quot;;
          return *this;
      }
  };
  
  int main() {
      SayWhat ohNo;
      // ohNo[1]; // Does not compile. Logic prevails.
      ohNo[0]; // you didn't! this compiles.
      return 0;
  }
  </code></pre>
  <p>The compiler is not complaining when passing the number 0 to the bracket operator accepting a string. Instead, this compiles and fails before entry to the method with:</p>
  <pre><code>terminate called after throwing an instance of 'std::logic_error'
    what():  basic_string::_S_construct null not valid
  </code></pre>
  <p>For reference:</p>
  <pre><code>&gt; g++ -std=c++17 -O3 -Wall -Werror -pedantic test.cpp -o test &amp;&amp; ./test
  &gt; g++ --version
  gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)
  </code></pre>
  <p><strong>My guess</strong></p>
  <p>The compiler is implicitly using the <code>std::string(0)</code> constructor to enter the method, which yields the same  problem (google the above error) for no good reason.</p>
  <p><strong>Question</strong></p>
  <p>Is there anyway to fix this on the class side, so the API user does not feel this and the error is detected at compile time?</p>
  <p>That is, adding an overload</p>
  <pre><code>void operator[](size_t t) {
      throw std::runtime_error(&quot;don't&quot;);
  }
  </code></pre>
  <p>is not a good solution.</p>