[英]Partial Method Specialization
我有一個 C++ class,在 Logger.hpp 中有一個模板方法,我想向它添加特化以支持其他類,例如 Player.hpp 中的特化。 我想我要實現的是所謂的“部分方法專業化”,如果我錯了請糾正我。
我嘗試了以下(簡化的)代碼:
記錄器.hpp
class Logger {
public:
template<typename T, typename... ArgTypes> void log(T message, ArgTypes... args) {
std::cout << message << std::endl;
// do more with args...
}
};
播放器.hpp
#include "Logger.hpp"
class Player {
public:
Player(const std::string &name) : name(name) {}
std::string getName() const { return name; }
private:
std::string name;
};
// add support for logger->log(myPlayer, 19, 11)
// (19 and 11 are arbitrary arguments and can be of any number and types)
// unfortunately this line does not compile
// (declaration is incompatible with function template "void Logger::log(T message, ArgTypes ...args)")
template<typename... ArgTypes> void Logger::log<Player>(Player message, ArgTypes... args) {
std::cout << "Player(name=" << message.getName() << ")" << std::endl;
// do more with args...
}
我應該如何將功能添加到我的記錄器 class 以允許我記錄我的播放器 class(以及以后的其他類)?
我不想在 Logger.hpp 中添加專業化。 應該可以像處理庫一樣處理 Logger.hpp,任何人都可以自由地在他們的代碼中添加對他們的類型的支持。
另請注意,我在鍵入的第一個參數之后傳遞了一個可變參數(typename ... ArgTypes)。
另請注意,在 C++ output class 上重載 << 運算符也不是一個選項,因為 cout 行稍后將被不同的代碼替換。
我找到了一些適用於我的特定情況的解決方法,它也可能是其他人遇到此類問題的解決方案。
我選擇了特定類型 std::string,而不是第一個日志參數 T 作為模板參數。 至於其他類,我只需添加一個 std::string 轉換運算符,它將生成我想要的任何字符串。
這對我來說很好,因為我最終要處理字符串,我想每次都對 args 做同樣的事情。 新代碼如下所示:
記錄器.hpp
class Logger {
public:
template<typename... ArgTypes> void log(std::string message, ArgTypes... args) {
std::cout << message << std::endl;
// do more with args...
}
};
播放器.hpp
#include "Logger.hpp"
class Player {
public:
Player(const std::string &name) : name(name) {}
std::string getName() const { return name; }
operator std::string() const {
return std::string("Player(name=") + name + ")";
}
private:
std::string name;
};
如果我不想使用字符串轉換,或者如果我想將一些參數傳遞給我的 function,另一種解決方案是使用 base 和 sub class。這樣的方法可能有效(未測試):
記錄器.hpp
class Loggable {
public:
virtual void logMe() = 0;
};
class Logger {
public:
template<typename T, typename... ArgTypes> void log(T message, ArgTypes... args) {
std::cout << message << std::endl;
// do more with args...
}
template<typename... ArgTypes> void log(Loggable *loggable, ArgTypes... args) {
loggable->logMe();
}
};
播放器.hpp
#include "Logger.hpp"
class Player : public Loggable {
public:
Player(const std::string &name) : name(name) {}
std::string getName() const { return name; }
void logMe() override {
std::cout << "Player(name=" << message.getName() << ")" << std::endl;
}
private:
std::string name;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.