引自免费微信小程序:皆我百晓生
为了实现一个可以存储任意类型模板数据且能在后续遍历输出的logMap
,你需要稍微调整一下你的设计。首先,你需要创建一个基类(例如LogBase
)来作为所有类型T
的共同父类,然后为每种类型创建一个派生类。接着,使用std::variant
来存储不同类型的值,并在容器中存储这些变体的指针。
以下是修改后的代码:
#include <iostream>
#include <map>
#include <string>
#include <variant>
class LogBase {};
template <typename T>
class Log final : public LogBase {
public:
explicit Log(const std::string& name, T value) : name(name), value(value) {}
const std::string& getName() const { return name; }
T getValue() const { return value; }
private:
std::string name;
T value;
};
using LogVariant = std::variant<std::unique_ptr<Log<int>>, std::unique_ptr<Log<double>>, std::unique_ptr<Log<std::string>>>;
using LogMap = std::map<const char*, LogVariant>;
template <typename T>
void collectLog(const char* name, T value) {
auto log = std::make_unique<Log<T>>(name, value);
logMap[name] = std::move(log);
}
void printLogs(const LogMap& logMap) {
for (const auto& entry : logMap) {
const auto& log = std::get<0>(entry.second); // 0对应的是std::unique_ptr<LogBase>
std::cout << "Name: " << log.getName() << ", Value: ";
if (std::holds_alternative<std::unique_ptr<Log<int>>>(entry.second)) {
std::cout << std::get<std::unique_ptr<Log<int>>>(entry.second)->getValue();
} else if (std::holds_alternative<std::unique_ptr<Log<double>>>(entry.second)) {
std::cout << std::get<std::unique_ptr<Log<double>>>(entry.second)->getValue();
} else if (std::holds_alternative<std::unique_ptr<Log<std::string>>>(entry.second)) {
std::cout << std::get<std::unique_ptr<Log<std::string>>>(entry.second)->getValue();
}
std::cout << std::endl;
}
}
int main() {
collectLog("IntLog", 42);
collectLog("DoubleLog", 3.14);
collectLog("StringLog", "Hello, World!");
printLogs(logMap);
return 0;
}
在这个例子中,我们使用了C++17的std::variant
来存储不同类型的数据,并通过std::unique_ptr<LogBase>
来确保类型安全。在遍历logMap
时,我们可以根据变体中的类型动态地访问并打印出每个日志的名称和值。当然,这只是一个基础示例,如果你需要支持更多类型,只需添加相应的派生类和变体类型即可。