Здравствуйте. Есть вопрос, как правильно задизайнить.
Есть простенький DSV-writer. Хочется путём лёгкой кастомизации превращаться его в CSV, TSV, etc. writer.
И тут у меня появились две соперничающие идеи, как эту кастомизацию сделать.
1.
template <typename Delimiter,
          typename LineTerminator,
          typename Quote,
          typename Comment>
struct Dialect
{
    using DelimiterType = Delimiter;
    using LineTerminatorType = LineTerminator;
    using QuoteType = Quote;
    using CommentType = Comment;
    Dialect() = default;
    Dialect(Delimiter delimiter1, LineTerminator lineTerminator1, Quote quote1, Comment comment1) :
            delimiter(delimiter1), lineTerminator(lineTerminator1), quote(quote1), comment(comment1)
    {}
    Delimiter delimiter;
    LineTerminator lineTerminator;
    Quote quote;
    Comment comment;
};
class Writer
{
    Dialect d;
public:
    Writer(const Dialect& dialect) : d(dialect) {}
    //...
};
const Dialect<char,char,char,char> CSV_Dialect = Dialect<char,char,char,char>(',', '\n', '"', '#');
const Dialect<char,char,char,char> TSV_Dialect = Dialect<char,char,char,char>('\t', '\n', '"', '#');
//.....
int main()
{
    Writer writer(CSV_Dialect);
}
Плюсы подхода - очень просто создать новый диалект. Просто создаём новую переменную типа диалект, задаём нужные нам типы внутри, пихаем туда любые значения, а потом скармливаем это Writer.
2.
template <typename Delimiter,
          typename LineTerminator,
          typename Quote,
          typename Comment>
struct Dialect
{
    using DelimiterType = Delimiter;
    using LineTerminatorType = LineTerminator;
    using QuoteType = Quote;
    using CommentType = Comment;
    Dialect() = default;
    Dialect(Delimiter delimiter1, LineTerminator lineTerminator1, Quote quote1, Comment comment1) :
            delimiter(delimiter1), lineTerminator(lineTerminator1), quote(quote1), comment(comment1)
    {}
    Delimiter delimiter;
    LineTerminator lineTerminator;
    Quote quote;
    Comment comment;
};
template <typename Delimiter,
          typename LineTerminator,
          typename Quote,
          typename Comment>
struct CSV_Dialect : public Dialect<Delimiter,LineTerminator,Quote,Comment>
{
    CSV_Dialect() : Dialect<Delimiter,LineTerminator,Quote,Comment>(',', '\n', '"', '#') {}
};
template <typename Delimiter,
          typename LineTerminator,
          typename Quote,
          typename Comment>
struct TSV_Dialect : public Dialect<Delimiter,LineTerminator,Quote,Comment>
{
    TSV_Dialect() : Dialect<Delimiter,LineTerminator,Quote,Comment>('\t', '\n', '"', '#') {}
};
template <typename Dialect>
class Writer
{
    Dialect d;
    //...
};
//.....
int main()
{
    Writer<CSV_Dialect> writer;
}
Тут проблема в том, что создать новый диалект сложнее.
Если у кого-то есть ещё идеи, как сделать лучше - милости прошу к обсуждению.






