Template klasy + wektor

0

Witajcie, mam problem z template połączonym z wektorem. Wektor działa na utworzonej strukturze. każdy element to 2 składowe (X, Y). Y jest zawsze intem i służy do zwiększania za każdym trafieniem na X. Natomiast X chciałbym umieścić w template. Niestety nie mogę sobie z tym poradzić.

licz::licz(char sign, int number)
{
	
znak = sign;
	iloscZnakow = number;
}

licz::licz(std::string word, int number)
{
	slowo = word;
	iloscSlow = number;
}

licz::licz(int random, int number)
{
	los = random;
	iloscLosowych = number;
}

mam takie konstruktory w klasie i wtedy po utworzeniu wektora i jawnym zadeklarowaniu np.

std::vector <licz> znaki;
char a;

bez problemu mogę dodać element do interesującego mnie wektora np.

znaki.push_back(licz(a, 1));

Jak mogę poradzić sobie z tym, żeby rozbić to na template zależne tylko od typu 1 składowej wektora? druga jest zawsze intem.

0

Zrób szablon klasy, gdzie piersza składowa będzie miała generowany typ

template <class T>
class licz 
{
    T val;
    int int_val;
...
} 

i użyj tej klasy w vectorze.

2
YooSy napisał(a):

Zrób szablon klasy, gdzie piersza składowa będzie miała generowany typ

template <class T>
class licz 
{
    T val;
    int int_val;
...
} 

i użyj tej klasy w vectorze.

Przecież licz<int> ma inny typ niż licz<char> więc jak chcesz zinstancjonować vector tego template?

Prawdopodobnie da się to zrobić prościej:

class Ilicz {
public:
    virtual ~Ilicz() {}
    //tutaj deklaracje metod, które chcesz wywoływać
    virtual int countOfSomething() = 0;
};

template <class T>
class licz : public Ilicz {
    T val;
    int int_val;

public:
    virtual int countOfSomething() override
    {
        return int_val;
    }

    licz(T val, int int_val)
        : val{ std::move(val) }
        , int_val{ int_val }
    {
    }
};

int main()
{
    std::vector<std::unique_ptr<Ilicz>> v;

    v.push_back(std::make_unique<licz<char>>('q', 42));
    v.push_back(std::make_unique<licz<std::string>>("string", 21));

    for (const auto& elem : v) {
        std::cout << elem->countOfSomething() << '\n';
    }
}

https://wandbox.org/permlink/saRDFX8iev9eZXJF

Edit:
możesz też użyć std::variant i std::visit:

template <class T>
class licz {
    T val;
    int int_val;

public:
    int countOfSomething() const
    {
        return int_val;
    }

    T getVal() const
    {
        return val;
    }

    licz(T val, int int_val)
        : val{ std::move(val) }
        , int_val{ int_val }
    {
    }
};

int main()
{
    std::vector<std::variant<licz<char>, licz<std::string>>> var;

    var.push_back(licz<std::string>("string", 21));
    var.push_back(licz<char>('q', 42));

    for (const auto& elem : var) {
        std::visit(
            make_overload(
                [](const licz<char>& x) {
                    std::cout << "jestem licz<char> val: " << x.getVal() << " int_val:" << x.countOfSomething() << '\n';
                },
                [](const licz<std::string>& x) {
                    std::cout << "jestem licz<std::string> val: " << x.getVal() << " int_val:" << x.countOfSomething() << '\n';
                }),
            elem);
    }

    return 0;
}

https://wandbox.org/permlink/vQyLWImXdeZAB4h2

Tutaj więcej o variant i make_overload: https://vittorioromeo.info/index/blog/variants_lambdas_part_1.html

0

@_0x666_: potrzebuję szablon klasy w którym utworzę utworzę wektor w którym 1 elementem będzie dana o różnym typie (string,int,char i własny typ color) a drugim elementem będzie stale int (licznik). Bez template budując zwykłe konstruktory i potem w mainie mogłem bez problemu utworzyć odpowiedni wektor. Tutaj niestety był problem. W pewnym momencie nawet ten szablon działał, ale wstyd było pokazywać jak to działa. Niestety termin mnie gonił z oddaniem tego projektu na zaliczenie i postanowiłem, że jednak zrobię na mapie. Program działa bez problemu. Za propozycje serdecznie dziękuję, w wolnej chwili z ciekawości przetestuję.

1 użytkowników online, w tym zalogowanych: 0, gości: 1