【问题标题】:C++ Is it possible to create a std::list of type T when a constructor is required for type T?当类型 T 需要构造函数时,C++ 是否可以创建类型 T 的 std::list?
【发布时间】:2023-03-21 01:12:01
【问题描述】:

例如:

class apple
{
public:
    string name;

    apple::apple(string name) : name(name)
    {
    }
};

如果我想制作一堆列表,每个列表都有苹果的类型,我想我可以做类似std::list<apple> empire("empire"), macintosh("macintosh") 的事情。基本上,我想在创建列表时为list<T> 声明的类 T 的构造函数传递参数。抱歉,如果我没有正确解释这一点,如果您有这种能力,请随时编辑我的问题。

谢谢

编辑这个问题似乎令人困惑,这可能是因为我举了一个不好的例子。我需要重新设计我的课程。 尽管我想要的是一个包含所有帝国苹果的列表,并且该列表中的每个苹果都有一个指定的帝国类型,但按照这个示例,我需要一个包含所有 macintosh 苹果和每个苹果的列表在该列表中具有指定类型的 macintosh。

所以在这里澄清一些或混淆一些。

class apple
{
public:
    string variety_name;
    string description;
    apple::apple(string variety_name, string description)
        : variety_name(variety_name), description(description)
    {
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    // Vlad from Moscow's answer
    std::list<apple> empire(1, apple("empire", "picked yesterday")),
        macintosh(1, apple( "macintosh", "picked yesterday")); 

    // Vaughn Cato's answer
    empire.push_back(apple("empire", "picked today"));
    macintosh.push_back(apple("macintosh", "picked today"));

    for(list<apple>::iterator it=empire.begin(); it != empire.end(); ++it)
    {
        cout << it->variety_name << " " << it->description << endl;
    }

    for(list<apple>::iterator it=macintosh.begin(); it != macintosh.end(); ++it)
    {
        cout << it->variety_name << " " << it->description << endl;
    }

    return 0;
}

因此,正如您所见,存储品种比每次存储更容易;我的班级显然需要重新设计,但这并没有降低答案的有效性。感谢大家的帮助

【问题讨论】:

  • 您至少需要复制构造函数,并且(在 C++11 中)也需要移动构造函数。
  • std::list&lt;apple&gt; empire 创建一个名为“empire”的苹果列表。你打算让帝国成为一个苹果列表还是一个苹果?
  • @Vaughn Empire 成为帝国苹果列表
  • 苹果帝国相关信息:en.wikipedia.org/wiki/Empire_%28apple%29
  • @test:从您的示例来看,您似乎希望将名称与列表关联,而不是与列表中的单个苹果关联,即使名称是苹果的一部分,所以我'正在尝试了解您的期望。

标签: c++ stl std stdlist


【解决方案1】:

当然,您可以使用emplace()emplace_front()emplace_back() 通过适当的构造函数就地构造对象:

std::list<apple> list;
list.emplace(list.end(), "one");
list.emplace_front("two");
list.emplace_back("three");

【讨论】:

    【解决方案2】:

    你可以的

    std::list<apple> a;
    a.push_back(apple("delicious"));
    

    【讨论】:

      【解决方案3】:

      在 C++11 中,您可以使用初始化列表:

      #include <list>
      #include <string>
      
      int main() {
          // C++11 initializer-list
          std::list<std::string> species = { "empire", "macintosh" };
      
      
          // Without C++11: You may initialize with an array:
          const char* species_array[] = { "empire", "macintosh" };
          std::list<std::string> species_list(
              species_array,
              species_array + sizeof(species_array)/sizeof(species_array[0]));
          return 0;
      }
      

      苹果是:

      int main() {
          // C++11 initializer-list
          std::list<apple> species = { apple("empire"), apple("macintosh") };
      
      
          // Without C++11: Initialize with an array:
          const apple species_arry[] = { apple("empire"), apple("macintosh") };
          std::list<apple> species_list(
              species_arry,
              species_arry + sizeof(species_arry)/sizeof(species_arry[0]));
          return 0;
      }
      

      【讨论】:

      • 我使用的是 Visual Studio 2010,我只能使用 Without C++11 方法,但它可以工作。
      【解决方案4】:

      这个

      apple(string name);
      

      是所谓的转换构造函数。它将 std::string 类型的对象转换为 apple 类型的对象。它可以在等待 aoole 类型的对象但获得 std::string 类型的对象时被编译器隐式调用。

      如果您将构造函数声明为显式,则无法这样做。例如

      explicit apple(string name);
      

      在这种情况下,您需要明确指定构造函数。例如

      std::list<apple> empire( 1, apple( "empire" ) ); 
      

      【讨论】:

      • @test 很抱歉,我不知道你编译了什么代码。至少您的类定义包含错误。构造函数定义不应具有限定名称。这不是 testapple::apple(string name) : name(name) {} 必须是 apple(string name) : name(name) {} 尽管 MS VC++ 等一些构造函数允许使用限定名称。我也有一个错字。添加第二个参数 1。我更新了我的帖子。
      • @Johan 谢谢。这是一个错字。一开始想push_back但是忘记改代码了。
      • Vlad 在您添加1 的编辑后,我能够编译,您能告诉我为什么会这样吗?迪特在你面前有一个可行的答案,所以我已经将他的标记为正确。
      • 哦,现在清楚了。它是大多数标准容器的通用构造函数,其第一个参数指定要添加到容器中的元素数量,第二个参数指定将分配给元素的初始值。例如,如果你想在一个列表中添加 10 个整数,它们的值都是 5,你可以写 std::list l( 10, 5 );
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-28
      • 2015-04-24
      • 2018-08-22
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多