#include <iostream>
#include <memory>

struct LoggingConfig {};

template<typename Derived>
class Logging {
public:
    explicit Logging(const LoggingConfig& config) {}

    static std::unique_ptr<Derived> CreateIfLoggingEnabled(const LoggingConfig& config) {
        return std::make_unique<Derived>(config);
    }
};

class LoggingString : public Logging<LoggingString> {
public:
    using Logging<LoggingString>::Logging;

    void writeLog(std::string str) { std::cout << "[LoggingString] " << str << std::endl; }
};

class LoggingInt : public Logging<LoggingInt> {
public:
    using Logging<LoggingInt>::Logging;

    void writeLog(int i) { std::cout << "[LoggingInt] " << i << std::endl; }
};

int main()
{
	auto logger1 = LoggingString::CreateIfLoggingEnabled(LoggingConfig{});
	logger1->writeLog("hello");
	
	auto logger2 = LoggingInt::CreateIfLoggingEnabled(LoggingConfig{});
	logger2->writeLog(12345);

	return 0;
}