【问题标题】:segfault in c++ templatesC ++模板中的段错误
【发布时间】:2018-02-03 01:09:26
【问题描述】:

我有一个关于 C++ 模板的问题。以下代码段错误。

template <typename T1, typename T2>
inline T1 const& max(T1 const &a, T2 const &b) {
    return a < b ? b : a;
}
int main() {
    std::cout << max(4.9, 4) << std::endl;
}

但是,删除 & 并且它会做正确的事情。

template<typename T1, typename T2>
inline T1 const max(T1 const &a, T2 const &b) {
    return a < b ? b : a;
}
int main() {
    std::cout << max(4.9, 4) << std::endl;
}

此外,只需使用 T 而不是 T1 和 T2 就可以了。

template<typename T>
inline T const& max(T const &a, T const &b) {
    return a < b ? b : a;
} 

int main() {
    std::cout << max(4, 5) << std::endl;
}

我在这里做错了什么?

【问题讨论】:

  • 请说明您使用的是什么编译器,包括版本号。如果是GCC,你用-Wall编译了吗?您可能会忽略导致未定义行为的警告。
  • 编译器应该告诉你 max() 调用返回对临时的引用。
  • 前两个代码sn-ps是否相同?

标签: c++ templates


【解决方案1】:

在前两个中,您正在返回对临时的引用。

为什么?好吧,您的函数返回类型 T1,但您必须转换您发送的类型之一。转换创建了一个正确类型的临时文件。那你就退货了。

由于临时死了,返回的引用被绑定到死对象。

您已经找到了解决方法。您要么不返回引用,要么采用相同类型的参数。

如果你看标准实现,它选择了第二种解决方案:采用相同类型的参数。

【讨论】:

    【解决方案2】:

    您应该始终在打开警告的情况下进行编译,请参阅https://wandbox.org/permlink/KkhFOJw6QNJ7rv7J。如果您打开了警告标志,编译器会帮助您并告诉您您做错了什么。

    这里发生的是提升(参见Return type of '?:' (ternary conditional operator)),您正在对intdouble 执行三元表达式。这样做会导致临时提升double。并且返回对临时的引用并在绑定其生命周期的函数返回之后引用该引用是未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-23
      • 2015-08-05
      • 2012-10-04
      • 1970-01-01
      相关资源
      最近更新 更多