Prevent function taking const std::string& from accepting 0 : <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;"here\n"; // To make sure we fail on function entry
        std::cout&lt;&lt;s&lt;&lt;"\n";
        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("don't");
}
</code></pre>

<p>is not a good solution.</p>
