Как инициализировать класс шаблона с другим шаблоном в качестве параметра? - PullRequest
0 голосов
/ 10 июня 2019

Я пытаюсь лучше понять шаблоны C ++ и не могу заставить приведенный ниже код работать так, как я хочу.

#include <iostream>
template <typename T>
class Amount {
public:
    T m_amount;

    Amount(T amount) : m_amount(amount) {
        //std::cout << __PRETTY_FUNCTION__ << "\n";
    }

    friend std::ostream &operator<<(std::ostream &out, const Amount &amount) {
        out << amount.m_amount;
        return out;
    }
};

template <typename T>
class Grams : public Amount<T> {
public:
    Grams(T amount) : Amount<T>(amount) {}
};

template <typename T>
class Milliliters : public Amount<T> {
public:
    Milliliters(T amount) : Amount<T>(amount) {}
};


template <typename T>
class Ingredient {
public:
    Amount<T> m_amount;
    std::string m_name;
    Ingredient(Amount<T> amount, std::string name) : m_amount(amount), m_name(name)
    {
        //std::cout << __PRETTY_FUNCTION__ << "\n";
        std::cout << "Ingredient name: " << m_name << ", amount: " << m_amount << "\n";
    }
};


class Bowl {
public:
    Ingredient<Milliliters<int>> m_ingredient1;
    Ingredient<Grams<int>> m_ingredient2;
    Bowl(Ingredient<Milliliters<int>> ingredient1, Ingredient<Grams<int>> ingredient2) :
    m_ingredient1(ingredient1),
    m_ingredient2(ingredient2)
    {
        //std::cout << __PRETTY_FUNCTION__ << "\n";
        std::cout << "Bowl with ingr1: " << m_ingredient1.m_name << ": " << m_ingredient1.m_amount << "\n";
        std::cout << "          ingr2: " << m_ingredient2.m_name << ": " << m_ingredient2.m_amount << "\n";
    }
    void Mix() {
        std::cout << "Mixing all ingredients in the bowl\n";
    }

};

int main() {

    Milliliters<int> amount_water {10};
    Milliliters<double> amount_milk {5.5};
    Grams<double> amount_flour {5.6};
    Grams<int> amount_butter {250};

    std::string name_water { "water" };
    std::string name_milk { "milk" };
    std::string name_flour { "flour" };
    std::string name_butter { "butter" };

    Ingredient<Milliliters<int>> Water {amount_water, name_water};
    Ingredient<Grams<int>> Butter {amount_butter, name_butter};

    Bowl bowl1 {Water, Butter};

    bowl1.Mix();

    return 0;
}

Как видите, Bowlимеет твердо принятый ингредиент.Я хочу, чтобы это был также шаблонный класс, чтобы я также мог добавить Milk ингредиент.

У меня было это раньше:

template <typename T1, typename T2>
class Bowl {
public:
    Ingredient<T1> m_ingredient1;
    Ingredient<T2> m_ingredient2;
    Bowl(Ingredient<T1> ingredient1, Ingredient<T2> ingredient2) :

[...]

    Ingredient<Milliliters<double>> Milk {amount_milk, name_milk};
    Ingredient<Grams<int>> Butter {amount_butter, name_butter};

    Bowl<Ingredient<Milliliters<double>>, Ingredient<Grams<int>>> bowl1 {Milk, Butter};

Но это говорит:

No matching constructor for initialization of 'Bowl<Ingredient<Milliliters<double> >, Ingredient<Grams<int> > >'

Что я здесь не так делаю или что я не правильно понимаю?

Ответы [ 2 ]

1 голос
/ 10 июня 2019

template s может быть сложным, поэтому давайте подумаем, каковы ваши T1 и T2.

Bowl<Ingredient<Milliliters<double>>, Ingredient<Grams<int>>>
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^  ^~~~~~~~~~~~~~~~~~~~~^
                  T1                           T2

Поскольку ваш Bowl конструктор использует Ingredient<T1>, Ingredient<T2>, он расширяется до:

Bowl<Ingredient<Ingredient<Milliliters<double>>>, Ingredient<Ingredient<Grams<int>>>>
1 голос
/ 10 июня 2019

Вы пробовали с

Bowl<Milliliters<double>, Grams<int>> bowl1 {Milk, Butter};
// ..^^^^^^^^^^^^^^^^^^^..^^^^^^^^^^   no more "Ingredient"

?

Я имею в виду ... если вы определяете

Bowl<Ingredient<Milliliters<double>>, Ingredient<Grams<int>>>

, у вас есть, что T1 равно Ingredient<Milliliters<double>> и T2 равно Ingredient<Grams<int>>.

Итак, конструктор, ожидая Ingredient<T1> и Ingredient<T2>, ждет Ingredient<Ingredient<Milliliters<double>>> и Ingredient<Ingredient<Grams<int>>>

Слишком много Ingredient s.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...