![](/img/trans.png)
[英]How do I produce a compiler error upon an attempt to instantiate a template subclass method for certain non-type values?
[英]How do I enable a template base upon comparison of values?
我試圖弄清楚如何根據兩個模板 arguments 之間的比較來“啟用”模板化方法。
例如:
enum class LoggerLevel {
FATAL = 0,
ERROR = 1,
WARNING = 2
};
template <LoggerLevel LOGGER_LEVEL>
class Logger {
public:
template <LoggerLevel LEVEL>
void log(const char* str);
};
如果 LOGGER_LEVEL < WARNING,我希望調用log<WARNING>()
編譯為空(一個空函數)
我知道這可以通過某種形式的模板專業化來實現。 我也一直在研究 std::greater_equal ,它看起來很有希望,但我不知道如何實現這種行為。
像這樣的東西。 當基於日志級別啟用或禁用重載時,可以通過使用std::enable_if來實現所需的行為。
#include <iostream>
#include <type_traits>
enum LogLevel {
FATAL = 0,
ERROR = 1,
WARNING = 2
};
template <LogLevel LOGGER_LEVEL>
class Logger {
public:
template <LogLevel MESSAGE_LEVEL>
typename std::enable_if<LOGGER_LEVEL < MESSAGE_LEVEL>::type
log(const char* /*str*/) {
// Do nothing
}
template <LogLevel MESSAGE_LEVEL>
typename std::enable_if<LOGGER_LEVEL >= MESSAGE_LEVEL>::type
log(const char* str) {
std::cout << str << std::endl;
}
};
int main() {
{
Logger<WARNING> logger;
logger.log<WARNING>("Warning 1!");
logger.log<ERROR>("Error 1!");
logger.log<FATAL>("Fatal 1!");
}
{
Logger<FATAL> logger;
logger.log<WARNING>("Warning 2!");
logger.log<ERROR>("Error 2!");
logger.log<FATAL>("Fatal 2!");
}
}
Output 將是:
Warning 1!
Error 1!
Fatal 1!
Fatal 2!
一種解決方案是使用 constexpr-if 僅編譯您想要的代碼
template <LoggerLevel LOGGER_LEVEL>
class Logger {
public:
template <LoggerLevel LEVEL>
void log(const char* str)
{
if constexpr (LEVEL >= LOGGER_LEVEL)
// ... code
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.