【问题标题】:std::vector vs std::initializer_list issue: undefined baheviorstd::vector vs std::initializer_list 问题:未定义的行为
【发布时间】:2016-05-09 15:54:07
【问题描述】:

我有这个辅助方法可以附加到一个链表(下面的代码):

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

我首先尝试像这样在 std::vector 中附加 1,5,7,9:

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

但它用 0,0,7,9 而不是 1,5,7,9 填充链表。任何想法为什么?

完整代码如下:

    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';                                                                            
    }                                 

【问题讨论】:

  • 你有没有通过代码来查看它在做什么?
  • 为什么你有任意数量的右尾间距?
  • 节点在两种情况下都存储一个悬空引用。
  • “这是完整的代码” Nuh-uh。阅读minimal reproducible example
  • @John 那你应该。这是非常重要的技能,大多数情况下它可以找到你的大部分问题。这是一个关于如何调试小程序的好链接:ericlippert.com/2014/03/05/how-to-debug-small-programs

标签: c++ c++11 vector initializer-list


【解决方案1】:

这里的一个编程错误是您的节点存储了引用const T&amp; val_;。改为存储值const T val_;

【讨论】:

  • 哦,所以我猜会有未定义的行为,这就是为什么我看到它适用于 initializer_list 而不是矢量?
  • 您还提到“一个编程错误”。你看到别人了吗?
  • @John 这是我注意到的第一件事,因为我避免引用成员。我没有发现其他任何东西。
猜你喜欢
  • 2023-02-07
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 2014-07-08
  • 1970-01-01
  • 1970-01-01
  • 2015-01-15
相关资源
最近更新 更多