C++ Is it possible to create a std::list of type T when a constructor is required for type T?

StackOverflow https://stackoverflow.com/questions/21080099

  •  27-09-2022
  •  | 
  •  

문제

For example:

class apple
{
public:
    string name;

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

If I want to make a bunch of lists each with the type of apple, I thought I could do something like std::list<apple> empire("empire"), macintosh("macintosh"). Basically I want to pass arguments for a constructor of class T declared by list<T> when I'm creating a list. Sorry if I'm not explaining this right, feel free to edit my question if you have that ability.

Thanks

EDIT This question seems to be confusing and it's probably because I gave a bad example. I need to redesign my class. Following this example though what I wanted is a list that is all empire apples and each apple in that list has a designated type of empire, and a list that is all macintosh apples and each apple in that list has a designated type of macintosh.

So to clarify some or confuse some more here we go.

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

So as you can see it would be easier to store the variety once rather than each time; my class obviously needs a redesign but that doesn't make the answers any less valid. Everyone thanks for your help

도움이 되었습니까?

해결책 3

In C++11 you may use an initializer-list:

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

With apples it is:

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

다른 팁

Sure, you can use emplace(), emplace_front() and emplace_back() to construct object in-place with appropriate constructor:

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

You can do

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

This

apple(string name);

is a so-called conversion constructor. It converts an object of type std::string to an object of type apple. It can be called implicitly by the compiler when it is awaiting an object of type aoole but gets an object of type std::string.

You could not do so if you would declare the constructor as explicit. For example

explicit apple(string name);

In this case your would need explicitly to specify the constructor. For example

std::list<apple> empire( 1, apple( "empire" ) ); 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top