【问题标题】:How do I add a string to a vector (and subsequently display it)?如何将字符串添加到向量(并随后显示它)?
【发布时间】:2019-08-10 05:22:32
【问题描述】:

我是 C++ 的 4 小时新手,并且已经用字符串向量碰了壁。尝试将多个字符串添加到字符串向量时,我不断出错。我想使用push_back

我也想显示这个字符串向量,但我不确定如何(我知道如何显示非向量)。鉴于我无法将字符串添加到字符串向量,我还没有尝试显示字符串向量。

profile.hpp

#include <iostream>
#include <vector>

class Profile 
{
private:
    std::string name;
    std::string city;
    std::string country;
    int age;
    std::vector<std::string> hobbies;

public:
    std::vector<std::string> add_hobbies(std::string new_hobbies);
};

profile.cpp

#include <iostream>
#include "profile.hpp"

Profile::Profile(std::string new_name, int new_age, std::string new_city, std::string new_country)
    : name(new_name), age(new_age), city(new_city), country(new_country) 
{}

void Profile::add_hobbies(std::string new_hobbies) 
{
    hobbies.push_back(new_hobbies);
}

app.cpp

#include <iostream>
#include "profile.hpp"
int main()
{
    Profile sam("Sam Drakkila", 30, "New York", "USA");
    sam.add_hobbies("Play golf", "Read books", "Eat tennis balls"); // This doesn't seem to work. 
}

g++ app.cpp profile.cpp。打印大量错误日志。

【问题讨论】:

标签: c++ class c++11 stdvector stdstring


【解决方案1】:

您的代码存在以下问题:

  1. 您已声明add_hobbies 返回std::vector&lt;std::string&gt;, 但在定义上你已经返回void。据推测,您应该声明为 void 函数,因为它似乎是一个 setter 函数。
  2. 其次,您传递的是多个字符串而不是单个字符串 你在这里定义:

    void Profile::add_hobbies(std::string new_hobbies) //>>> as per defenition, only one string can be passed!
    //                        ^^^^^^^^^^^^^^^^^^^^^^^^
    

    如果你想传递任意数量的字符串,你可以改用std::initializer_list&lt;std::string&gt;

  3. 第三,您在头文件中缺少构造函数声明。添加 在类profile.hpp的定义中

    Profile(std::string new_name, int new_age, std::string new_city, std::string new_country);
    
  4. 最后但同样重要的是,您需要在其中包含 &lt;string&gt; 标头 为了使用std::string(信用@πάντα ῥεῖ)

也就是说,(See live online)

#include <iostream>
#include <vector>
#include <string>           // std::string
#include <initializer_list> // std::initializer_list

class Profile 
{    
private:
    // ... other members
    std::vector<std::string> hobbies;

public:
    // ... other member functions
    void add_hobbies(std::initializer_list<std::string> new_hobbies)
  //^^^^             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    {
        hobbies.reserve(hobbies.size() + new_hobbies.size()); // reserve memory to avoid, unwanted reallocations
        for (const auto& hobby : new_hobbies) hobbies.emplace_back(hobby);
    }
};

int main() 
{
    Profile sam{};
    sam.add_hobbies({ "Play golf", "Read books", "Eat tennis balls" }); // now works
    //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

或者使用 variadic templates 功能 fold expression(See live online)

#include <iostream>
#include <vector>
#include <string>      // std::string
#include <type_traits> // std::enable_if, std::is_same, std::common_type

using namespace std::literals;

class Profile 
{
private:
    // ... other members
    std::vector<std::string> hobbies;

public:
    // ... other member functions
    template<typename... Args> // sfinae to restrict the Args type to be only std::string s
    std::enable_if_t<std::is_same_v<std::common_type_t<Args...>, std::string>>
        add_hobbies(Args&& ... args)
    {
        hobbies.reserve(hobbies.size() + sizeof...(Args));
        (hobbies.emplace_back(std::forward<Args>(args)), ...);
    }
};

int main() 
{
    Profile sam{};
    sam.add_hobbies("Play golf"s, "Read books"s, "Eat tennis balls"s); // now works
    //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

【讨论】:

  • 只是一个小注释,为了让 reserve 按预期工作,您需要当前大小 + 初始化列表大小(而不仅仅是初始化列表)。
  • @JeJo OP 的代码中也缺少#include &lt;string&gt;
  • @πάνταῥεῖ 是的,我错过了...已添加。感谢您指出。
【解决方案2】:

您在类声明中将add_hobbies 声明为返回一个向量。

【讨论】:

    【解决方案3】:

    您的代码中有一些错误:

    缺少构造函数声明:

    Profile(std::string new_name, int new_age, std::string new_city, std::string new_country);
    

    声明的返回类型与add_hobbies 的定义不匹配,应为void(因为您没有返回任何内容)。

    void Profile::add_hobbies(std::string new_hobbies) { // ... } 
    

    您还尝试传递其中的 3 个,而函数只有 1 个参数:

    void add_hobbies(std::string const& h1, std::string const& h2, std::string const& h3);
    
    // ... 
    
    void Profile::add_hobbies(std::string const& h1, std::string const& h2, std::string const& h3) {
      hobbies.push_back(h1);
      hobbies.push_back(h2);
      hobbies.push_back(h3);
    }
    

    【讨论】:

    • "const char[] 而非 std::string 传递给 add_hobbies..." 这不是问题。参数中的const char*(不是[])将隐式转换为std::string。其他一切似乎都恰到好处。 :)
    • @TrebledJ 哎呀
    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 2023-03-12
    相关资源
    最近更新 更多