I want to be able to initialize each field of a class either using move semantics or copy semantics. The constructors will all use essentially the same code for construction, like this:
LogRecord::LogRecord(const Logger &logger, LogLevel level, const std::wstring &message)
: level(level), logger_name(logger.GetName()), message(message), sequence_number(LogRecord::record_count++), source_class_name(), source_method_name(), time(std::chrono::system_clock::now()) {
}
LogRecord::LogRecord(const Logger &logger, LogLevel level, std::wstring &&message)
: level(level), logger_name(logger.GetName()), message(message), sequence_number(LogRecord::record_count++), source_class_name(), source_method_name(), time(std::chrono::system_clock::now()) {
}
LogRecord::LogRecord(const Logger &logger, LogLevel level, const std::wstring &message, const std::wstring &source_class_name, const std::wstring &source_method_name)
: level(level), logger_name(logger.GetName()), message(message), sequence_number(LogRecord::record_count++), source_class_name(source_class_name), source_method_name(source_method_name), time(std::chrono::system_clock::now()) {
}
LogRecord::LogRecord(const Logger &logger, LogLevel level, std::wstring &&message, const std::wstring &source_class_name, const std::wstring &source_method_name)
: level(level), logger_name(logger.GetName()), message(message), sequence_number(LogRecord::record_count++), source_class_name(source_class_name), source_method_name(source_method_name), time(std::chrono::system_clock::now()) {
}
LogRecord::LogRecord(const Logger &logger, LogLevel level, const std::wstring &message, std::wstring &&source_class_name, const std::wstring &source_method_name)
: level(level), logger_name(logger.GetName()), message(message), sequence_number(LogRecord::record_count++), source_class_name(source_class_name), source_method_name(source_method_name), time(std::chrono::system_clock::now()) {
}
LogRecord::LogRecord(const Logger &logger, LogLevel level, std::wstring &&message, std::wstring &&source_class_name, const std::wstring &source_method_name)
: level(level), logger_name(logger.GetName()), message(message), sequence_number(LogRecord::record_count++), source_class_name(source_class_name), source_method_name(source_method_name), time(std::chrono::system_clock::now()) {
}
etc.
Is there a better way to go about this than simply declaring a constructor for each possible combination, like this?
class LogRecord {
public:
LogRecord(const Logger &logger, LogLevel level, const std::wstring &message);
LogRecord(const Logger &logger, LogLevel level, std::wstring &&message);
LogRecord(const Logger &logger, LogLevel level, const std::wstring &message, const std::wstring &source_class_name, const std::wstring &source_method_name);
LogRecord(const Logger &logger, LogLevel level, std::wstring &&message, const std::wstring &source_class_name, const std::wstring &source_method_name);
LogRecord(const Logger &logger, LogLevel level, const std::wstring &message, std::wstring &&source_class_name, const std::wstring &source_method_name);
LogRecord(const Logger &logger, LogLevel level, std::wstring &&message, std::wstring &&source_class_name, const std::wstring &source_method_name);
LogRecord(const Logger &logger, LogLevel level, const std::wstring &message, const std::wstring &source_class_name, std::wstring &&source_method_name);
LogRecord(const Logger &logger, LogLevel level, std::wstring &&message, const std::wstring &source_class_name, std::wstring &&source_method_name);
LogRecord(const Logger &logger, LogLevel level, const std::wstring &message, std::wstring &&source_class_name, std::wstring &&source_method_name);
LogRecord(const Logger &logger, LogLevel level, std::wstring &&message, std::wstring &&source_class_name, std::wstring &&source_method_name);
...
private:
std::wstring message, source_class_name, source_method_name;
...
};
Here is a simplified form to make it a bit easier to read.
Object
is the class with the members, and Member
is the typename of the members. The Member
type has both a copy constructor and a move constructor defined.
Basically, my question was how I could do the following with less code duplication:
class Object {
public:
Object(const Member &x, const Member &y, const Member &z) : x(x), y(y), z(z) {}
Object(Member &&x, const Member &y, const Member &z) : x(x), y(y), z(z) {}
Object(const Member &x, Member &&y, const Member &z) : x(x), y(y), z(z) {}
Object(Member &&x, Member &&y, const Member &z) : x(x), y(y), z(z) {}
Object(const Member &x, const Member &y, Member &&z) : x(x), y(y), z(z) {}
Object(Member &&x, const Member &y, Member &&z) : x(x), y(y), z(z) {}
Object(const Member &x, Member &&y, Member &&z) : x(x), y(y), z(z) {}
Object(Member &&x, Member &&y, Member &&z) : x(x), y(y), z(z) {}
private:
Member x, y, z;
}