【发布时间】:2018-04-19 23:27:34
【问题描述】:
我正在开发一个小型 C++ 项目,为此我创建了一个漂亮且方便的 std::ostream 包装器,名为 Logger。
在类中我定义了一个模板化操作符:
template<typename T, typename std::enable_if_t<std::is_arithmetic<T>::value, T> = 0>
friend Logger& operator<<(Logger& logger, const T& logMessage) {
return logger << std::to_string(logMessage); // there is also an operator overload which takes a std::string& as argument.
}
当模板以整数类型实例化时,例如int 或long,模板的作用就像一个魅力。
所以声明
someLoggerInstance << 123 << 456ULL << "\n";
编译得很好。
但是,如果我将语句更改为
someLoggerInstance << 12.3 << "\n";
编译器对我大喊模板无法实例化。
来自编译器的错误信息:
候选模板被忽略:替换失败[with T = double]:非类型模板参数不能有类型'typename std::enable_if_t::value, double>'(又名'double')
问题出在哪里?
我尝试将std::is_arithmetic<T> 替换为std::is_integral<T> 并使用std::is_floating_point<T> 添加第二个模板化函数,但这并没有改变任何东西,整数模板被实例化,但浮点模板不是,导致相同错误信息如上。
如果我为 double 类型创建额外的重载
friend Logger& operator<<(Logger& logger, const double& logMessage) {
return logger << std::to_string(logMessage);
}
问题变得更糟,从那时起编译器试图在最后传递"\n",以下消息让我很恼火:
候选函数不可行:第二个参数没有从 'const unsigned char [1]' 到 'const double' 的已知转换
和
候选函数不可行:第二个参数没有从 'const unsigned char [1]' 到 'const std::string'(又名 'const basic_string, allocator >')的已知转换
任何帮助或建议都会很好! 谢谢!
编辑
感谢您的快速帮助。
现在像这样更改模板:
template<typename T, typename TEnable = std::enable_if_t<std::is_arithmetic<T>::value && !std::is_same<T, char>::value, T>>
friend Logger& operator<<(Logger& logger, const T& logMessage);
【问题讨论】:
标签: c++ templates primitive-types