2016-04-11 21 views
8

私はSUSE Enterprise Linux 11でGCC 4.7.2とBoost 1.58.0を使用しています。基本的にポリゴンのリストを通ってそれらを計算する次のコードスニペットがあります。長さ幅。 std :: minmax関数で 'auto'キーワードを使用すると、私は奇妙な出力を見ています。比較するために、タイプが明示的に宣言されている第2の変数も宣言しています(つまり、dim vs 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; 
} 

このループの最初の反復では、期待される出力が正しいです。私は「DIM1」をコメントアウトして同じコードを再実行した場合

380 420 
380 420 
380 420 

しかし、(すなわち、単に自動暗くを持っている)、私がのstd :: MINMAXとの奇妙な結果が得られます。

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使用しない場所のような場合の一つです。 autoが推測されます何

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

std::minmax参照のペアを返します。しかし、delta()は一時的なものを返します。だから、書くとき:

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

dimは2つの宙ぶらりんの参照を保持しています。しかし、あなたが書くとき:

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)}); 

をしかし、タイプを明示的に指定することをお勧めします。それは私にはエラーが起きにくいようです。

関連する問題