簡體   English   中英

如何根據值比較啟用模板?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM