John
John

Reputation: 3105

std::vector vs std::initializer_list issue: undefined bahevior

I have this helper method to append to a linked list (code below):

void append(const std::initializer_list<T>& vals) {                               
            for (const auto& val : vals)                                                    
              append(val);                                                                  
} 

I first tried to append 1,5,7,9 with std::vector like this:

void append(const std::vector<T>& vals) {                               
            for (const auto& val : vals)                                                    
              append(val);                                                                  
} 

But it filled the linked list with 0,0,7,9 instead of 1,5,7,9 . Any ideas why?

Here is the entire code:

    template <typename T>                                                               
    class LinkedList {                                                                  
    private:                                                                            
      struct Node {                                                                     
        const T& val_;                                   
        std::shared_ptr<Node> next_ = nullptr;                                          
        Node(const T& val) : val_(val) {}                                               
      };                                                                                
    public:                                                                             
      std::shared_ptr<Node> head_ = nullptr;                                            
      std::shared_ptr<Node> current = nullptr;                                          

      // could be optimized                                                                                 
      void append(const std::initializer_list<T>& vals) {                               
        for (const auto& val : vals)                                                    
          append(val);                                                                  
      }                                                                                 

      void append(const T& val) {                                                       
        if (!head_) {                                                                   
          head_ = std::make_shared<Node>(val);                                          
          return;                                                                       
        }                                                                               
        current = head_;                                                                
        while (current->next_)                                                          
          current = current->next_;                                                     
        current->next_ = std::make_shared<Node>(val);                                   
      }                                                                                 

      template <typename Func>                                                          
      void for_each(Func f) {                                                           
        current = head_;                                                                
        while (current) {                                                               
          f(current->val_);                                                             
          current = current->next_;                                                     
        }                                                                               
      }                                                                                 


    };                                                                               

    int main() {                                                                     
      LinkedList<int> lst;                                                           
      lst.append({1,5,7,9});                                                         
      auto printer = [](int val) {                                                   
        std::cout << val << " ";                                                     
      };                                                                             
      lst.for_each(printer);                                                         
      std::cout << '\n';                                                                            
    }                                 

Upvotes: 0

Views: 162

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136355

One programming error here is that your Node stores a reference const T& val_;. Store the value instead const T val_;.

Upvotes: 4

Related Questions