为什么编译器将此方法的返回类型报告为void?

时间:2017-08-14 03:01:27

标签: c++

我正在为std::vector

开发自定义包装器
#include <vector>

template<typename Key, typename Value> 
struct keyed_vector {

  typedef Value value_type;
  typedef Key size_type;
  std::vector<Value> values;

  keyed_vector( std::initializer_list<Value> init ) : values(init) {}

  size_type size() const { return static_cast<size_type>(values.size()); }
};

我想确保在尝试使用return时编译器出错 size()作为size_t的值是理智的,所以我写了一个快速测试:

#include <cassert>
int main() {
  struct my_size_type {
    size_t t;
    explicit my_size_type(size_t t) : t(t) {}
  };

  keyed_vector<my_size_type, int> 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);
  }
}

虽然编译器确实失败了,但我得到的错误信息与我预期的不同:

$ 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.

我原本预计&#34; error: no viable conversion from 'my_size_type' to 'size_t' (aka 'unsigned long')&#34;。

为什么编译器(Apple LLVM version 8.1.0 (clang-802.0.42))会报告 这里将vec.size()的返回类型设为void

1 个答案:

答案 0 :(得分:0)

啊,我想我found the reason in the comments to another question。这是因为我使用了初始化列表。

如果我将代码切换为:

size_t actual_size = vec.size(); // this should be a compiler error

然后我得到了更明确的错误:

$  g++ --stdlib=libc++ -std=c++1y -Wall -Wextra -Werror keyed_vector_example.cpp
keyed_vector.cpp:28:10: error: no viable conversion from 'size_type' (aka 'my_size_type') to 'size_t' (aka 'unsigned long')
  size_t actual_size = vec.size(); // this should be a compiler error
         ^             ~~~~~~~~~~
1 error generated.

看起来其他编译器为支持的初始化列表提供了更好的错误消息,所以如果这真的困扰我,我应该提出clang的问题。