涉及shared_ptr列表表达式的C++编译错误排查请求
问题分析与修复方案
咱们一步一步拆解你遇到的问题:
1. 直接触发编译错误的运算符优先级问题
你写的表达式 (*(iter).get())->getData() 犯了运算符优先级的错误:成员访问运算符 . 的优先级比解引用 * 更高,所以编译器会先尝试调用 iter.get()——但 std::list 的迭代器根本没有 get() 成员方法,这就是你看到编译错误的直接原因。
正确的逻辑应该是:先解引用迭代器得到 std::shared_ptr<A<T1>>,再调用它的 get() 方法。你可以用两种更合理的写法实现:
// 写法1:先解引用迭代器,再调用shared_ptr的get() (*iter).get()->getData() // 写法2:用->直接穿透迭代器和shared_ptr,代码更简洁 iter->get()->getData()
2. 隐藏的拼写错误
你的B类里还有一个typedef拼写不一致的问题:
using typAContainter = std::list<std::shared_ptr<A<T1>>>; // 这里少了一个'e',应为typeAContainer private: typeAContainer C; // 这里的类型名是typeAContainer,和上面的typedef不匹配
这个错误会导致编译器找不到 typeAContainer 类型,必须先修正拼写不一致的问题。
3. 潜在的运行时未定义行为
即使修复了上面两个问题,这段调试代码依然有严重的逻辑漏洞:在B类的构造函数中,容器 C 还没有被填充任何元素,C.begin() 返回的是空容器的尾后迭代器(空容器的begin和end指向同一个位置),直接解引用这个迭代器会触发未定义行为(大概率导致程序崩溃)。你需要确保容器中有元素后,再进行迭代和解引用操作。
修复后的完整代码示例
#include <list> #include <memory> #include <iostream> template<typename T> class A{ public: T& getData() { return data; } // 注意:data是引用,需确保它指向的对象生命周期足够长 A(T& d) : data(d) {} private: T& data; }; template<typename T1, typename T2> class B{ public: using typeAContainer = std::list<std::shared_ptr<A<T1>>>; // 修正拼写错误 B(int, T2&); private: typeAContainer C; // 现在与typedef名称一致 }; template<typename T1, typename T2> B<T1, T2>::B(int I, T2& rData){ #ifdef DEBUG // 先给容器添加一个测试元素,避免空容器迭代的风险 T1 dummyData{}; C.emplace_back(std::make_shared<A<T1>>(dummyData)); auto iter = C.begin(); // 使用正确的表达式访问数据 std::cout << iter->get()->getData() << std::endl; // 其实还可以更简洁:shared_ptr支持直接用->调用指向对象的方法,无需get() // std::cout << (*iter)->getData() << std::endl; #endif }
额外提一句:std::shared_ptr 本身支持 -> 运算符,可以直接调用指向对象的成员方法,所以你其实不需要调用 get(),直接写 (*iter)->getData() 就能达到目的,代码会更简洁。
内容的提问来源于stack exchange,提问作者user9196120
相关产品推荐
相关产品推荐

