如何用std::map的find()访问std::pair为键的list值?
std::list from Your Parse Table Map Alright, let's break this down step by step. I see a couple of issues with your current approach to using find() on your parseTable, plus a key detail about std::list that's probably tripping you up.
First, let's fix the find() usage: your current if condition is checking the iterator returned by find() directly, which won't work as expected. The find() method returns an iterator pointing to the matching element (if found) or parseTable.end() (if not found). You need to compare the iterator to end() to confirm a match was found.
Once you've confirmed you have a valid entry, accessing the std::list<Symbol> values requires remembering that std::list is a doubly linked list—it doesn't support random access (so you can't use [] to grab elements by index directly). Instead, you'll use iterators or range-based for loops to traverse the list, or std::next to jump to a specific position.
Full Example Code
Here's how to properly use find() and access the list elements:
// Create the key pair from your stack and current symbol auto lookupKey = std::make_pair(stack_symbol.top(), current_symbol); // Search the map for the key auto tableIterator = parseTable.find(lookupKey); // Check if we found a matching entry if (tableIterator != parseTable.end()) { // Get a reference to the list (avoids copying the entire list) const std::list<Symbol>& productionRule = tableIterator->second; // Option 1: Iterate through all elements in the list std::cout << "Applying production rule: "; for (const Symbol& sym : productionRule) { // Replace this with your actual logic (e.g., push to parser stack) std::cout << sym << " "; } std::cout << "\n"; // Option 2: Access a specific element (e.g., the 2nd element, index 1) size_t targetIndex = 1; if (targetIndex < productionRule.size()) { // Use std::next to move the iterator to the target position auto targetIterator = std::next(productionRule.begin(), targetIndex); Symbol targetSymbol = *targetIterator; // Use targetSymbol as needed } // Option 3: Access the first/last elements directly if (!productionRule.empty()) { Symbol firstSymbol = *productionRule.begin(); Symbol lastSymbol = *productionRule.rbegin(); // Use these symbols } } else { // Handle the case where no production rule exists (syntax error) std::cerr << "Error: No production rule found for the current state and symbol!\n"; }
Key Notes
- Iterator Check: Always compare the iterator from
find()toparseTable.end()—this is the only reliable way to know if the key was found. std::listLimitation: Sincestd::listdoesn't support random access,std::nextis the way to jump to a specific index. Keep in mind this operation takes O(n) time, where n is the index.- Performance Tip: If you frequently need to access elements by index, consider replacing
std::list<Symbol>withstd::vector<Symbol>as the map's value type.std::vectorsupports O(1) random access with the[]operator, which will be more efficient for that use case.
内容的提问来源于stack exchange,提问作者Jorge López

