C++中auto&绑定string::begin()返回值编译报错原因咨询
编译失败根本原因
- 基础认知误区:
std::string的迭代器并非原生char*指针。从报错信息可以看出,当前使用的MSVC STL实现中,string迭代器是独立封装的自定义类std::_String_iterator,仅操作接口和原生指针兼容,本身是独立的类类型对象。
错误写法触发编译失败的直接逻辑
报错代码核心行:
auto &c = str.begin(); // compile error
str.begin()的返回值是临时生成的迭代器对象,属于右值范畴。按照C++语法规则,非常量左值引用(即此处auto&推导得到的引用类型)不允许绑定到右值,编译器无法完成引用绑定操作,因此抛出C2440类型转换错误。
对应编译错误信息:
Error C2440 Cannot transform 'std::_String_iteratorstd::_String_val<std::_Simple_types<_Elem>>' to'std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>'错误本质是非const左值引用绑定右值时的类型不匹配。
第二种写法可正常编译运行的逻辑
可正常运行的代码核心行:
auto &c = *str.begin(); // success
对迭代器执行解引用操作*str.begin()时,返回值是字符串首字符的左值引用(类型为char&,直接指向string对象内部存储的首字符内存)。此时auto&会自动推导为char&类型,完全符合左值引用绑定左值的语法要求,因此可以正常编译,后续对c的修改会直接作用到原字符串的对应字符上。
补充说明
如果一定要绑定迭代器的引用,需使用const左值引用或右值引用,示例如下:
const auto& c1 = str.begin(); // 合法,const左值引用允许绑定右值 auto&& c2 = str.begin(); // 合法,右值引用允许绑定右值
以上两种写法仅能通过编译,实际使用价值极低:绑定临时迭代器的引用和直接拷贝迭代器auto c = str.begin();的效果没有本质区别,反而会增加代码的理解成本,不推荐在生产代码中使用。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

