2016-04-11 95 views
8

我在SUSE Enterprise Linux 11上使用GCC 4.7.2和Boost 1.58.0。我有以下代码片段,它基本上会通过多边形列表来计算它们长度宽度。当使用std :: minmax函数使用'auto'关键字时,我看到奇怪的输出。为了进行比较,我还声明了第二个变量,其中明确声明了类型(即,dim与dim1)。使用'auto'和std :: minmax观察奇怪的行为

namespace gtl = boost::polygon; 
typedef gtl::polygon_90_data<int> LayoutPolygon; 
typedef gtl::rectangle_data<int> LayoutRectangle; 
static LayoutFeatureVec 
calc_stats(LayoutPolygonSet const& lp) 
{ 
    LayoutFeatureVec v; 
    LayoutFeature f; 
    LayoutRectangle y; 
    for (LayoutPolygon const& p : lp) { 
     // Compute bounds. 
     gtl::extents(y, p); 

     // Get width/length (shorter/longer). 
     // FIXME: Why does this not work with auto?? 
     cout << gtl::delta(y, gtl::HORIZONTAL) << " " << gtl::delta(y, gtl::VERTICAL) << endl; 

     auto dim = std::minmax(gtl::delta(y, gtl::HORIZONTAL), 
          gtl::delta(y, gtl::VERTICAL)); 

     std::pair<int, int> dim1 = std::minmax(gtl::delta(y, gtl::HORIZONTAL), 
              gtl::delta(y, gtl::VERTICAL)); 

     cout << dim.first << " " << dim.second << endl; 
     cout << dim1.first << " " << dim1.second << endl; 

     <snip> 
     v.push_back(f); 
    } 

    return v; 
} 

对于此循环的第一次迭代,期望的输出是正确的。

380 420 
380 420 
380 420 

但是,如果我注释掉“DIM1”,然后重新运行相同的代码(即,只是有自动变暗),我得到的std ::极小极大奇怪的结果。

380 420 
140737295994126 140737295994126 

我在做什么错在这里?

这是最小的例子(根据下面的答案编辑)。

#include <iostream> 
#include <algorithm> 
#include <boost/polygon/polygon.hpp> 

using namespace std; 

namespace gtl = boost::polygon; 
using namespace gtl::operators; 

int main(int argc, char** argv) 
{ 
    gtl::rectangle_data<int> x(0,0,5,5); 

    auto dim = std::minmax(gtl::delta(x, gtl::HORIZONTAL), gtl::delta(x, gtl::VERTICAL)); 
    cout << dim.first << " " << dim.second << endl; 

    return 0; 
} 

回答

13

这是在哪里使用auto作为类型说明符的情况下一个。 std::minmax返回一对引用

template< class T > 
std::pair<const T&,const T&> minmax(const T& a, const T& b); 

这就是auto将演绎。但delta()返回一个临时。所以当你写:

auto dim = std::minmax(gtl::delta(y, gtl::HORIZONTAL), 
         gtl::delta(y, gtl::VERTICAL)); 

dim是持有两个悬挂引用。但是当你写:

std::pair<int, int> dim1 = std::minmax(...); 

你只是直接持有这些值。这就是为什么这可以工作,但auto没有。您正在执行的额外转换会阻止您持有悬挂引用。


另外,对于完整性,您可以使用的minmax不同的过载不返回引用:

template< class T > 
std::pair<T,T> minmax(std::initializer_list<T> ilist); 

刚刚涉及到一些额外的括号:

auto dim2 = std::minmax({gtl::delta(y, gtl::HORIZONTAL), 
         gtl::delta(y, gtl::VERTICAL)}); 

但我建议明确指定类型。这似乎不太容易出错。