【问题标题】:type deduction failing for auto stdMaxInt = std::max<int>;auto stdMaxInt = std::max<int> 的类型推导失败;
【发布时间】:2016-02-15 19:43:26
【问题描述】:

将 GCC 4.8.4 与 g++ --std=c++11 main.cpp 一起使用会输出以下 error

error: unable to deduce ‘auto’ from ‘max<int>’
auto stdMaxInt = std::max<int>;

对于这个代码

#include <algorithm>

template<class T>
const T& myMax(const T& a, const T& b)
{
    return (a < b) ? b : a;
}

int main()
{
    auto myMaxInt = myMax<int>;
    myMaxInt(1, 2);

    auto stdMaxInt = std::max<int>;
    stdMaxInt(1, 2);
}

为什么它适用于myMax,但不适用于std::max?我们可以让它与std::max一起工作吗?

【问题讨论】:

  • 我不知道您的问题的确切答案,但我认为这与 std::max 在操作数符合条件时被重载为 const 表达式这一事实有关。您的版本没有这样的重载,因此没有歧义。解决这个问题而不让自己沉浸在细节中的最简单方法可能是在这种使用场景中简单地使用 myMax(或 lambda,例如),但只需在其实现中调用 std::max
  • @Ike std::max 被另一个签名重载以获取第三个参数,一个比较对象。编译器不知道打算使用哪个重载。
  • decltype(auto) stdMaxInt = ... with c++14 显示清晰信息
  • 哦,我明白了,我也错过了超载。现在我对 constexpr 重载感到好奇——这是否构成某种歧义,以及如何在捕获到 auto 时解决它。
  • @Ike 好像c++14出来以后,所有的版本都变成了constexpr,所以真的没有过载。

标签: c++ auto function-templates type-deduction template-instantiation


【解决方案1】:

因为std::max是一个重载函数,所以它不知道你要创建指向哪个重载的指针。您可以使用static_cast 选择您想要的重载。

auto stdMaxInt = static_cast<const int&(*)(const int&, const int&)>(std::max<int>);

【讨论】:

    【解决方案2】:

    @JamesRoot 的 static_cast 答案有效,但根据我的口味,我更喜欢 lambda:

    auto stdMaxInt = [](int const& L, int const& R) -> int const& { return std::max(L, R); };
    

    当传递给算法时,这可能具有更好的内联能力的优势(未经测试)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      • 2015-08-02
      • 1970-01-01
      相关资源
      最近更新 更多