title: Why does the compiler report the return type of this method as void?
body: <p>I'm working on a custom wrapper for <code>std::vector</code></p>
  
  <pre><code>#include &lt;vector&gt;
  
  template&lt;typename Key, typename Value&gt; 
  struct keyed_vector {
  
    typedef Value value_type;
    typedef Key size_type;
    std::vector&lt;Value&gt; values;
  
    keyed_vector( std::initializer_list&lt;Value&gt; init ) : values(init) {}
  
    size_type size() const { return static_cast&lt;size_type&gt;(values.size()); }
  };
  </code></pre>
  
  <p>I wanted to make sure that the compiler error when trying to use the return
  value of <code>size()</code> as a <code>size_t</code> was sane, so I wrote a quick test:</p>
  
  <pre><code>#include &lt;cassert&gt;
  int main() {
    struct my_size_type {
      size_t t;
      explicit my_size_type(size_t t) : t(t) {}
    };
  
    keyed_vector&lt;my_size_type, int&gt; vec{};
    {
      size_t actual_size {vec.size().t}; // this should compile cleanly
      assert(actual_size == 0u);
    }
    {
      size_t actual_size {vec.size()}; // this should be a compiler error
      assert(actual_size == 0u);
    }
  }
  </code></pre>
  
  <p>And while the compiler did fail, the error message I got was different than I expected:</p>
  
  <pre><code>$ g++ --stdlib=libc++ -std=c++1y -Wall -Wextra -Werror keyed_vector_example.cpp
  keyed_vector_example.cpp:28:10: error: no viable conversion from 'void' to 'size_t' (aka 'unsigned long')
    size_t actual_size {vec.size()}; // this should be a compiler error
           ^           ~~~~~~~~~~~~
  1 error generated.
  </code></pre>
  
  <p>I would have expected "<code>error: no viable conversion from 'my_size_type' to 'size_t' (aka 'unsigned long')</code>".</p>
  
  <p>Why is the compiler (<code>Apple LLVM version 8.1.0 (clang-802.0.42)</code>) reporting the
  return type of <code>vec.size()</code> as <code>void</code> here?</p>