Миксины и шаблоны функций - это два разных способа предоставления поведения широкому набору типов, если эти типы удовлетворяют некоторым требованиям.
Например, давайте предположим, что я хочу написать некоторый код, которыйпозволяет мне сохранять объект в файл, если этот объект предоставляет функцию-член toString
(это довольно глупый пример, но потерпите меня).Первое решение состоит в том, чтобы написать шаблон функции, подобный следующему:
template <typename T>
void toFile(T const & obj, std::string const & filename)
{
std::ofstream file(filename);
file << obj.toString() << '\n';
}
...
SomeClass o1;
toFile(o1, "foo.txt");
SomeOtherType o2;
toFile(o2, "bar.txt");
Другое решение - использовать миксин, используя CRTP :
template <typename Derived>
struct ToFile
{
void toFile(std::string const & filename) const
{
Derived * that = static_cast<Derived const *>(this);
std::ofstream file(filename);
file << that->toString() << '\n';
}
};
struct SomeClass : public ToFile<SomeClass>
{
void toString() const {...}
};
...
SomeClass o1;
o.toFile("foo.txt");
SomeOtherType o2;
o2.toFile("bar.txt");
Что такоеплюсы и минусы этих двух подходов?Есть ли любимый, и если да, то почему?