首页 > 解决方案 > 如何根据值比较启用模板?

问题描述

我试图弄清楚如何根据两个模板参数之间的比较来“启用”模板化方法。

例如:

enum class LoggerLevel {
    FATAL = 0,
    ERROR = 1,
    WARNING = 2
};

template <LoggerLevel LOGGER_LEVEL>
class Logger {
public:
    template <LoggerLevel LEVEL>
    void log(const char* str);
};

log<WARNING>()如果 LOGGER_LEVEL < WARNING,我想调用编译为空(一个空函数)

我知道这可以通过某种形式的模板专业化来实现。我也一直在研究 std::greater_equal ,它看起来很有希望,但我不知道如何实现这种行为。

标签: c++templates

解决方案


像这样的东西。当基于日志级别启用或禁用重载时,可以通过使用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!");
    }
}

输出将是:

Warning 1!
Error 1!
Fatal 1!
Fatal 2!

推荐阅读