c++ - GCC 上 map 迭代器错误的自动声明

标签 c++ c++11 gcc auto c++17

我有一个 map 定义为:

std::map<unsigned int, std::string> spCalls;  

我还有一个函数,在给定键的情况下返回字符串。它被定义为:

std::string spGetCallString(unsigned int key)
{
    auto iter{ spCalls.find(key) };

    return iter->second;
}

尝试使用 GCC 编译时,出现错误

error: base operand of '->' has non-pointer type
'std::initializer_list < std::_Rb_tree_iterator < std::pair < const unsigned int, std::basic_string < char> > > >'

 return iter->second;"

我只是无法理解这一点,我不明白为什么我的代码不能工作。感谢您的帮助。

最佳答案

在 C++17 之前,auto type deduction for braced initializer 将始终产生 std::initializer_list 的实例化类型, 所以对于 auto iter{ spCalls.find(key) }; , iter 的类型将是 std::initializer_list<std::map<unsigned int, std::string>::iterator> ,这与用法完全不符。

从 C++17 开始,您将获得正确的类型,即 std::map<unsigned int, std::string>::iterator .

In direct-list-initialization (but not in copy-list-initalization), when deducing the meaning of the auto from a braced-init-list, the braced-init-list must contain only one element, and the type of auto will be the type of that element:

auto x1 = {3}; // x1 is std::initializer_list<int>
auto x2{1, 2}; // error: not a single element
auto x3{3};    // x3 is int (before C++17 it was std::initializer_list<int>)

如果您的编译器仍然不支持,您可以将大括号初始化器更改为其他初始化器,例如

auto iter = spCalls.find(key);
auto iter(spCalls.find(key));

关于c++ - GCC 上 map 迭代器错误的自动声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41013480/

相关文章:

c++ - 共享指针如何工作?

c++ - 如何使用 C++11 std::move 语义。我尝试编写代码,得到的输出有些不同

c - 为什么 scanf() 会导致此代码中的无限循环?

c++ - 带接口(interface)的动态转换

c++ - 为什么互斥锁与原子操作的不同之处在于前者是操作系统级别,后者是处理器级别?

c++11 - 迭代 c++11 std::array 的前 N ​​个元素

multithreading - 显示通过事件发送到 Qt GUI 的 Opencv 图像

c - Lua C编译-llua错误

c - GCC 中的动态分配指针数组不匹配

c++ - idl 和 odl 的区别