当前位置: 首页 > 知识库问答 >
问题:

c模板实例化适用于int、long等,但不适用于float、double等

濮阳唯
2023-03-14

我正在做一个小的C项目,为此我创建了一个漂亮且方便的<code>std::ostream</code>包装器,名为<code>Logger</code>。

在类内部,我定义了一个模板化的操作符:

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.
}

当模板实例化为整数类型时,如intlong,模板就像一个符咒。因此,声明

someLoggerInstance << 123 << 456ULL << "\n";

它编译得很好。

但是,如果我将语句更改为

someLoggerInstance << 12.3 << "\n";

编译器向我喊道模板无法实例化。

来自编译器的错误消息:

Candidate template ignored: substitution failure [with T = double]: a non-type template parameter cannot have type 'typename std::enable_if_t::value, double>' (aka 'double')

问题出在哪里?

我试图替换< code > STD::is _算术

如果我为类型<code>double</code>创建额外的重载

friend Logger& operator<<(Logger& logger, const double& logMessage) {
    return logger << std::to_string(logMessage);
}

问题变得更糟,从那时起,编译器试图在最后传递"\n",用以下消息惹恼了我:

Candidate function not viable: no known conversion from 'const unsigned char [1]' to 'const double' for 2nd argument

Candidate function not viable: no known conversion from 'const unsigned char [1]' to 'const std::string' (aka 'const basic_string, allocator >') for 2nd argument

任何帮助或建议都很好!谢谢!

谢谢你的快速帮助。

现在像这样更改了模板:

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);

共有3个答案

夏谦
2023-03-14

要解决您的第一个问题,另一种SFINAE是使用std::enable_if_t来允许返回类型的替换失败...

template <typename T>
std::enable_if_t<std::is_arithmetic<T>::value, Logger&>
friend operator<<(Logger& logger, const T& logMessage)
{
    return logger << std::to_string(logMessage);
}

你的第二个问题是因为std::is_arithmetic

殷宇
2023-03-14

当< code>T是double时,这个东西< code>std::enable_if_t

但是非类型模板参数被明确禁止为浮点类型。您的问题的正确最小示例如下:

template<double d> // this is ill-formed
void foo() {}

基本原理是模板是根据非类型参数的确切值进行专门化的。这对于直接相等比较有问题的类型来说是一个问题。

只需将std::enable_if_t解析为有效类型,例如用0初始化的指针或int

鲍钊
2023-03-14

更新模板以使用类型模板参数:

template
<
    typename T
,   typename TEnabled = typename std::enable_if_t<std::is_arithmetic<T>::value, T>
>
friend Logger & operator <<(Logger & logger, const T & logMessage) {
    return logger << std::to_string(logMessage);
}
 类似资料:
  • 问题内容: 嗨,我只是简单地尝试在www.example.com上获取h1标签,该标签显示为“ Example Domain”。该代码适用于http://www.example.com,但不适用于https://www.exmaple.com。我该如何解决这个问题?谢谢 问题答案: PhantomJSDriver不支持(所有)DesiredCapabilities。 你会需要: 记录在这里:htt

  • 所以我使用这种方法写入文件,它在windows上运行完全正常,但在mac上运行时,它会创建文件,但它们是空的。 我知道数据是正确的,因为它打印正确。感谢您的任何帮助,这真的让我绊倒了。

  • 列名称的类型为int[] 上述查询适用于postgresql,但不适用于hsqldb,甚至适用于sql 尝试的hsqldb版本:2.2.9和2.3.0 在hsqldb中工作的sql是从table_name中选择x,unnest(column_name)y(x)x和y不是该表的列。

  • 编辑:Android Studio很慢地告诉我已弃用。由于某种原因,直到编写并运行代码很久之后,它才告诉我。然而,问题仍然存在。我只是想在我的问题中加入这个发现。 我有一个充当指南针的ImageView。在真实设备上一切都正常,但在我的模拟器上,扩展控件对ImageView没有影响。 如果我在模拟器上使用谷歌地图,我可以看到指南针在工作。如果我的应用程序在真实设备上运行,为什么它的工作原理不一样?

  • 问题内容: 在Java中,当我使用以下命令时: 我收到与不当类型相关的错误。我通过分别使用Character和Integer而不是char和int解决了我的问题。但是,我很难弄清楚为什么HashMap无法处理原始数据类型。 问题答案: 通用参数只能绑定到引用类型,而不能绑定到原始类型,因此您需要使用相应的包装器类型。试试吧。 但是,我很难弄清楚为什么HashMap无法处理原始数据类型。 这是由于类

  • 我能够成功地打电话给邮递员: /mfp/api/az/v1/token和 /mfpadmin/management-apis/2.0/runtimes/mfp/applications 我正在获取从/mfp/api/az/v1/token接收的承载令牌,并将其添加到/mfp/applications的授权标头中。 我收到了来自两者的200个响应,并从每个API中获取了预期的信息。 然后,我选择从P