代码之家  ›  专栏  ›  技术社区  ›  Chris Reid

C++将更好的方法将char *字符串放入STD::vector < string >?

  •  -1
  • Chris Reid  · 技术社区  · 7 年前

    我正在填充一个字符串向量,该向量来自 煤焦* 通过将它们放置在std::vector中

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <vector>
    #include <stdexcept>
    
    
    // safe function for putting char* strings into a std::vector<std::string>
    template <typename T, typename C>
    std::vector<T> & safe_emplace( std::vector<T>& vec, C& c)
    {
      if ( !c )  return  vec;
    
      vec.emplace_back(c);
    
      return vec;
    
    }
    
    
    // variadic version
    template <typename T, typename C, typename...  Args>
    std::vector<T> & safe_emplace( std::vector<T>& vec, C& c, Args... args)
    {
    
      safe_emplace(vec, c); 
    
      return safe_emplace( vec, args...);
    
    }
    
    
    // initializer list version
    template <typename T>
    std::vector<T> & safe_emplace( std::vector<T>& vec, const std::initializer_list<std::string> il)
    {
      for (auto& s: il)
        vec.emplace_back(s);
    
      return vec;
    }
    
    
    
    
    
    int main( int argc, char* argv[])
    {
      std::vector<std::string> svec;
    
      char one[] = "string one";
    
      char two[] = "string two";
    
      char three[] = "string three";
    
      char* d = new char[10];
    
      char* n = NULL;
    
      std::strncpy(d, "0123456789\0", 10);
    
      safe_emplace(svec, one);   // char[]
    
      safe_emplace(svec, two, three); // variadic
    
      safe_emplace(svec, d);  // char* 
    
      safe_emplace(svec, n); // char* NULL
    
      safe_emplace(svec,   "five", "four", "three", "two", "one", nullptr);
    
      safe_emplace(svec,   {"A", "B", "C", "D", "E"} );
    
    
    
      for (auto s : svec)
        std::cout << s << "\n";
    
      delete[] d; // clean up d (new)
    
    
      return 0;
    }
    

    我特别想处理空字符的情况* 我决定跳过它,而不是创建一个空字符串。

    模板。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Remy Lebeau    7 年前

    这段代码可以工作,但看起来有点笨重,需要三个模板来覆盖变量和初始值设定项列表。

    不太可能,因为你必须处理可变模板和 initializer_list

    我决定跳过它,而不是创建一个空字符串。

    那么你应该提供一个超负荷的 safe_emplace() char* 与其他类型分开的数据。

    #include <iostream>
    #include <string>
    #include <vector>
    #include <cstring>
    
    // rename the actual emplacement functions to avoid unwanted
    // recursive loops in the variadic template iteration...
    
    template <typename Container>
    Container& do_safe_emplace(Container &c, const char *value)
    {
        if (value) c.emplace_back(value);
        return c;
    }
    
    template <typename Container>
    Container& do_safe_emplace(Container &c, const typename Container::value_type &value)
    {
        c.emplace_back(value);
        return c;
    }
    
    // this overload is needed to handle when 'args...' becomes blank
    // at the end of the variadic template loop iteration...
    template <typename Container>
    Container& safe_emplace(Container &c)
    {
        return c;
    }
    
    template <typename Container, typename T, typename... Args>
    Container& safe_emplace(Container &c, const T &value, Args... args)
    {
        do_safe_emplace(c, value); 
        return safe_emplace(c, args...);
    }
    
    template <typename Container, typename T>
    Container& safe_emplace(Container &c, const std::initializer_list<T> il)
    {
        for (auto& value: il)
            do_safe_emplace(c, value);
        return c;
    }
    
    int main()
    {
        std::vector<std::string> svec;
    
        char one[] = "string one";
        char two[] = "string two";
        char three[] = "string three";
        std::string four = "string four";
        char* d = new char[11]; // <- need room for null terminator
        char* n = NULL;
    
        std::strncpy(d, "0123456789", 11);
    
        safe_emplace(svec, one);   // char[]
        safe_emplace(svec, two, three, four); // variadic
        safe_emplace(svec, d);  // char* 
        safe_emplace(svec, n); // char* NULL
        safe_emplace(svec, "five", "four", std::string("three"), "two", "one", nullptr);
        safe_emplace(svec, {"A", "B", "C", "D", "E"} );
    
        for (auto &s : svec)
            std::cout << s << "\n";
    
        delete[] d; // clean up d (new)
    
        return 0;
    }
    

    Live Demo

    推荐文章