使用通过模板注入的模板化类型
Use templated type injected via a template
这是我第一次尝试应用确实很难掌握的概念。我创建了一个通用记录器类型,它可以在编译时决定日志级别是否足够高以供输出。这是编译器资源管理器上的问题示例:https://godbolt.org/z/2u4HhB。这是记录器:
static const int debug = 1;
static const int info = 2;
static const int warn = 3;
static const int error = 4;
static const int fatal = 5;
template<int level, bool should_log = false>
struct logger_function {
static void log(std::string message) {
// Do nothing in the default case.
}
};
template<int level>
struct logger_function<level, true> {
static void log(std::string message) {
std::cerr << "[" << level << "] : " << message << std::endl;
}
};
template<int minLevel>
struct std_err_logger {
template<int levelValue>
struct level {
static constexpr bool shouldLogResult = levelValue >= minLevel;
typedef logger_function<levelValue, shouldLogResult> log_function;
static void log(std::string message) {
log_function::log(message);
}
};
};
它是这样使用的:std_err_logger<debug>::level<info>::log("Message.");
到目前为止效果很好。当我尝试通过另一个模板注入记录器类型时,问题就开始了——毕竟我以后可能更喜欢记录到一个文件中。
template<typename logger>
class log_client {
log_client() {
logger::level<fatal>::log("Worked!");
}
};
并将类型注入客户端:
int main() {
log_client<std_err_logger<debug>> log();
return 0;
}
但是强大的g++编译器心情并不愉快:
src/alsa/alsa_frame_recorder.h: In constructor ‘alsa::log_client<logger>::log_client()’:
src/alsa/alsa_frame_recorder.h:21:31: error: ‘::log’ has not been declared
logger::level<1>::log("Worked!");
^~~
src/alsa/alsa_frame_recorder.h:21:31: note: suggested alternative: ‘long’
logger::level<1>::log("Worked!");
^~~
long
问题是您错误地使用了依赖模板。你应该写:
template<typename logger>
class log_client {
log_client() {
logger::template level<fatal>::log("Worked!");
}
};
这里需要template
的解释请参考this question。
这是我第一次尝试应用确实很难掌握的概念。我创建了一个通用记录器类型,它可以在编译时决定日志级别是否足够高以供输出。这是编译器资源管理器上的问题示例:https://godbolt.org/z/2u4HhB。这是记录器:
static const int debug = 1;
static const int info = 2;
static const int warn = 3;
static const int error = 4;
static const int fatal = 5;
template<int level, bool should_log = false>
struct logger_function {
static void log(std::string message) {
// Do nothing in the default case.
}
};
template<int level>
struct logger_function<level, true> {
static void log(std::string message) {
std::cerr << "[" << level << "] : " << message << std::endl;
}
};
template<int minLevel>
struct std_err_logger {
template<int levelValue>
struct level {
static constexpr bool shouldLogResult = levelValue >= minLevel;
typedef logger_function<levelValue, shouldLogResult> log_function;
static void log(std::string message) {
log_function::log(message);
}
};
};
它是这样使用的:std_err_logger<debug>::level<info>::log("Message.");
到目前为止效果很好。当我尝试通过另一个模板注入记录器类型时,问题就开始了——毕竟我以后可能更喜欢记录到一个文件中。
template<typename logger>
class log_client {
log_client() {
logger::level<fatal>::log("Worked!");
}
};
并将类型注入客户端:
int main() {
log_client<std_err_logger<debug>> log();
return 0;
}
但是强大的g++编译器心情并不愉快:
src/alsa/alsa_frame_recorder.h: In constructor ‘alsa::log_client<logger>::log_client()’:
src/alsa/alsa_frame_recorder.h:21:31: error: ‘::log’ has not been declared
logger::level<1>::log("Worked!");
^~~
src/alsa/alsa_frame_recorder.h:21:31: note: suggested alternative: ‘long’
logger::level<1>::log("Worked!");
^~~
long
问题是您错误地使用了依赖模板。你应该写:
template<typename logger>
class log_client {
log_client() {
logger::template level<fatal>::log("Worked!");
}
};
这里需要template
的解释请参考this question。