【问题标题】:STL template function to return a pairSTL 模板函数返回一对
【发布时间】:2017-09-15 19:51:11
【问题描述】:

我正在尝试编写一个从 STL 容器返回一对值的函数。

template <typename T>
std::pair<typename T::value_type,typename T::value_type> getMinMax(T &container) {

    auto min = *(container.begin());
    auto max = *(container.begin());

    for (auto it : container) {
        if (min > (*it) ) {
            min = (*it);
        }
        if (max < (*it) ) {
            max = (*it);
        }
    }
    return std::make_pair(min, max);
};

int main() {
    std::vector<int> c{1, 2, 3, 4, 5};
    auto p = getMinMax(c);
    std::cout << "min: " << p.first << " max: " << p.second << "\n";
}

我收到一个错误:

错误:间接需要指针操作数('int' 无效) 如果 (min > (*it) ) {

我不知道该怎么处理。

除了这个错误,还有更好的方法来实现所需的行为吗?

【问题讨论】:

  • 有没有更好的方法来实现所需的行为?。是的,std::minmax_element
  • @user1211030 在此代码中 sn-p for (auto it : container) { if (min > (*it) ) { min = (*it); } 它不是迭代器或指针。它具有值类型。所以删除取消引用。
  • for range 返回元素,而不是迭代器
  • @user1211030 通常该函数具有未定义的行为,因为容器可以是空的。:)

标签: c++ algorithm c++11 templates std-pair


【解决方案1】:

for range 返回元素,而不是迭代器。所以你的循环应该是这样的:

for (const auto& e : container) {
    if (min > e) {
        min = e;
    }
    if (max < e) {
        max = e;
    }
}

【讨论】:

    【解决方案2】:
    template <typename T>
    std::pair<typename T::value_type, typename T::value_type> getMinMax(T &container) {
    
        auto min = *(container.begin());
        auto max = *(container.begin());
    
        for (const auto& element : container) { /* ERROR WAS HERE, FOR RANGE LOOPS RETURN AN ELEMENT */
            if (min > element) {
                min = element;
            }
            if (max < element) {
                max = element;
            }
        }
        return std::make_pair(min, max);
    };
    

    嘿!这应该可行,您将minmax 设置为取消引用的element,这当然不是我们想要的。 :)

    此外,如果container 为空,您可能会得到未定义的行为。也许你应该添加一些检查来检查。

    【讨论】:

    • std::pair 必须有值,不能为空。如果容器为空,则返回默认值std::pair 将包含可能使调用者混淆为有效的值,而实际上它们不是有效的。也许返回一个std::pair&lt;std:::pair, bool&gt;,而bool 表示成功/失败(类似于std::map::insert())?否则,只需抛出异常即可。
    • 我不知道这个。谢谢
    • @Remy Lebeau 如果容器为空,则呈现的函数具有未定义的行为。:)
    • @VladfromMoscow:是的,我知道。格雷厄姆在他的回答中说了这么多:“你可以得到未定义的行为,例如,如果容器是空的。也许你应该添加一些检查来检查 ",我通过提供函数可以向调用者报告它无法为空容器返回有效的std::pair 的方式来回答。
    【解决方案3】:

    对于初学者来说,当容器为空时,函数可能具有未定义的行为,因为可能会尝试取消引用空容器的迭代器。

    在这样的循环中

    for (auto it : container) {
        if (min > (*it) ) {
            min = (*it);
        }
    

    不正确地使用了解引用。

    您可以使用标准算法std::minmax_element。但是,它与您的代码不同。它返回第一个最小元素和最后一个最大元素。所以你应该重写算法std::minmax_element,这样ir将返回第一个最小元素(指向第一个最小元素的迭代器)和第一个最大元素(指向第一个最大元素的迭代器)。

    函数可以定义例如下面的方式

    #include <iostream>
    #include <utility>
    #include <vector>
    #include <iterator>
    
    template <typename T>
    auto getMinMax( T &container ) 
        -> std::pair<decltype( container.begin() ), decltype( container.begin() )> 
    {
        auto min = container.begin();
        auto max = container.begin();
    
        if ( !container.empty() )
        {
            for ( auto it = container.begin(); ++it != container.end();  )
            {
                if ( *it < *min ) min = it;
                else if ( *max < *it ) max = it;
            }
        }
    
        return { min, max };
    }
    
    int main() 
    {
        std::vector<int> v = { 5, 2, 3, 7, 1, 4, 9, 8, 6 };
    
        auto minmax = getMinMax( v );
    
        std::cout << "Minimum = " << *minmax.first 
                  << " at position " << std::distance( v.begin(), minmax.first )
                  << " and maximum = " << *minmax.second
                  << " at position " << std::distance( v.begin(), minmax.second )
                  << std::endl;
    
        return 0;
    }
    

    程序输出是

    Minimum = 1 at position 4 and maximum = 9 at position 6
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      • 1970-01-01
      • 2022-10-21
      相关资源
      最近更新 更多