Я пытаюсь лучше понять шаблоны 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> > >'
Что я здесь не так делаю или что я не правильно понимаю?