【问题标题】:Compilation error on using dependent scope as type for std::less in default argument在默认参数中使用依赖范围作为 std::less 类型的编译错误
【发布时间】:2014-02-24 20:08:27
【问题描述】:

在我添加第二个参数以使其更通用之前,以下怪物运行良好:

template<class IterableType, class Comparator>
typename IterableType::iterator GetMinimum(IterableType collection, Comparator comparator =
        std::less<typename IterableType::iterator>
        )
{
    typename IterableType::iterator iter = collection.begin();
    typename IterableType::iterator result = iter;

    for(; iter != collection.end(); ++iter)
    {
        if(comparator(iter, result))
            result = iter;
    }

    return result;
}

目前它给出以下错误:

121:9: error: expected primary-expression before ‘)’ token

对于行号:

118: template<class IterableType, class Comparator>
119: typename IterableType::iterator GetMinimum(IterableType collection, Comparator comparator =
120:         std::less<typename IterableType::iterator>
121:         )

我有#included &lt;functional&gt; 所以std::less 是有效的。有人可以指出我在这里做错了什么吗?

【问题讨论】:

    标签: c++ templates stl


    【解决方案1】:

    你需要说

    Comparator comparator = std::less<typename IterableType::iterator>()
    

    在参数列表中,即末尾带有额外的括号以默认构造 less 对象。

    但我仍然不确定它是否会起作用,因为不要认为编译器可以像这样推断 Comparator 类型。 编辑:@battery 在 cmets 中确认这不起作用。

    正确的做法是提供std::less作为默认模板参数,然后你可以说

    template <typename IterableType, typename Comparator = std::less<...>>
    GetMinimum(IterableType collection, Comparator comparator = Comparator{})
    

    它会默认构造用户选择的任何 Comparator 类型。

    【讨论】:

    • 感谢 Tristan,第一种方法奏效了!稍后我也会尝试其他建议。
    • 对不起,纠正自己,第一种方法不起作用。此代码是共享库的一部分并已编译。但是在尝试使用代码时,我确实得到了错误:模板参数扣除/替换失败。建议进行编辑并删除第一种方法。
    • @battery 好吧,公平地说,我确实说过我认为它不会起作用!它并不意味着非此即彼——第二种方法是正确的方法。我会编辑答案,以防其他人将来遇到这个问题。
    【解决方案2】:

    std::less&lt;...&gt; 是一种类型。如果要将其用作参数的默认值,则需要实例化它,即std::less&lt;...&gt;()

    但是,这种方法无论如何都行不通,因为编译器无法使用参数的默认值推断模板参数。 STL 处理这个问题的方式就是重载函数,提供一个模板接受一个额外的比较器参数,另一个不接受(并且只使用std::less)。例如,见std::max_element

    【讨论】:

      【解决方案3】:

      签名应该是:

      template<
          class IterableType,
          class Comparator = std::less<typename IterableType::iterator> >
      typename IterableType::iterator
      GetMinimum(IterableType collection, Comparator comparator)
      

      将默认值移动到模板参数中。

      对于一个默认模板参数和一个默认参数

      template<
          class IterableType,
          class Comparator = std::less<typename IterableType::iterator> >
      typename IterableType::iterator
      GetMinimum(
          IterableType collection, Comparator comparator = Comparator() )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        相关资源
        最近更新 更多