15

この応答では:

https://stackoverflow.com/a/14382318/1676605

このプログラムは次のように与えられます:

std::vector<int> vi{ 0, 2, 4 };
std::vector<std::string> vs{ "1", "3", "5", "7" };
for (auto i : redi::zip(vi, vs))
    std::cout << i.get<0>() << ' ' << i.get<1>() << ' ';

の型がわからないauto iため、専門知識を再利用して例から学ぶことが難しくなっています。auto iこれがchar iリターンに変わるものです

In function ‘int main()’:|
/data/cbworkspace/TestZip/TestZip.cpp|14|error: cannot convert ‘boost::iterator_facade<boost::zip_iterator<boost::tuples::tuple<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> > > >, boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >, boost::random_access_traversal_tag, boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >, long int>::reference {aka boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >}’ to ‘char’ in initialization|
/data/cbworkspace/TestZip/TestZip.cpp|14|warning: unused variable ‘i’ [-Wunused-variable]|
||=== Build finished: 1 errors, 1 warnings (0 minutes, 0 seconds) ===|

そこからタイプを考えてみてください。

autoC++ 11で an の変数の型を特定する方法はありますか? より明確にするために、私はstructこのようなものを持っています:

struct EventData
{
    // return value from redi::zip<std::vector<PriceQuote>, std::vector<PriceQuote>> what goes here????? So REDI::Zip is zipping PriceQuote, PriceQuote of bids and asks.
};

struct PriceQuote
{
   double price;
   double size;
};
4

8 に答える 8

24

auto を char に変更して、エラー メッセージを読んでみてください。

于 2013-07-23T18:25:38.300 に答える
10

なぜその型を構造体に入れたいのですか? 実際にはそのように使用するようには設計されていません (私が書いたはずです!) が、必要に応じて と を使用decltypestd::declvalて型を決定できます ( の実装を変更しても、正しい答えが得られますredi::zip) 。

struct EventData
{
  // type returned by redi::zip
  typedef decltype(redi::zip(std::declval<V1>(), std::declval<V2>())) zipper_type;

  // type referred to by zipper_type::iterator
  typedef std::iterator_traits<zipper_type::iterator>::value_type zipped_type;

  zipper_type m_zipper;
};

NB の を作成するのはなぜtypedefですかstruct? これは C ではなく C++ です。やめてください。

auto i のタイプがわからないため、専門知識を再利用して例から学ぶことが難しくなっています。

それに慣れる。std::bind戻るタイプを知っていますか?std::mem_fn戻るタイプを知っていますか?ラムダ式が作成する型を知っていますか? いいえ、知る必要はありません。知っておく必要があるのは、それが持つプロパティと、それを使用して何ができるかだけです

于 2013-07-23T21:30:30.610 に答える
8

見つけたでしょうか

for (boost::iterator_facade<
       boost::zip_iterator<
         boost::tuples::tuple<std::vector<int>::iterator,
                              std::vector<int>::iterator>
       >,
       boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >,
       boost::random_access_traversal_tag,
       boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >,
       long int
     >::reference i : redi::zip(vi, vs))
    std::cout << i.get<0>() << ' ' << i.get<1>() << ' ';

分かりやすい?

于 2013-07-23T18:34:37.027 に答える
3

何を返すかを理解する最善の方法redi::zip()は、何を返すかを調べることredi::zip()です。=) 私の IDE では、Ctrl キーを押しながら をクリックすると、すぐにジャンプできますzip()。あなたのものは同様の機能を提供していませんか? zip()ループ内でカーソルを合わせるだけfor()で、戻り値の型を含む関数シグネチャを示すツールチップを取得することもできます。

「auto」を手動で置き換えるものを入力するには、とにかくそれを確認する必要があります。 auto は、他の方法では宣言できない型を宣言できるという大きな利点を提供します (次のような複雑なことをしない限り、ラムダの戻り値など)。 decltype には、 autoについて気に入らないのと同じ欠陥があります)。

IDE が C++11 をさらにサポートすると、インテリセンスがうまく機能し、型が何であるかがより明確になります。1年以内に、最新のIDEのほとんどは、ホバーしたときにautoの真のタイプを教えてくれるでしょう。

autoの利点は損失をはるかに上回りますが、確かに小さな損失があり、優れた IDE サポートによってさらに小さくなります。ほとんどすべてに長所と短所があります。

于 2013-07-23T18:26:38.443 に答える
3

に対する答え

「コンパイル時に'auto' 変数の実際の型を判別するにはどうすればよいですか」

答え:

次のようにコンパイルしてみてください。

auto foo = function_that_returns_unknown_type() // "what type could foo be?"
int a = foo;

コンパイラ エラー メッセージは、「型XXX(それが何であれ) を変換できないint」ことを示します。そこにあなたのタイプがあります

于 2020-11-15T10:31:39.007 に答える
1

Windows: Visual Studio の組み込みデバッガーが型情報を提供します。

Linux: gdb でコードをデバッグしptype <varname>、exe がスコープ内の変数で壊れたら送信します。出力例 - この場合、次のように置き換えることができますが、これautovector<uint8_t>::const_iterator特に明らかではありません。

type = class __gnu_cxx::__normal_iterator
                  <unsigned char const*,
                   std::vector<unsigned char,
                               std::allocator<unsigned char>
                              > 
                  >
       [with _Iterator = const unsigned char *, 
       _Container = std::vector<unsigned char, std::allocator<unsigned char> >] 
        {
   protected:
       _Iterator _M_current;

   public:
     __normal_iterator(void);
     __normal_iterator(const unsigned char * const&);
     reference operator*(void) const;
     _Iterator operator->(void) const;
     __gnu_cxx::__normal_iterator<unsigned char const*, _Container> & operator++(void);
     __gnu_cxx::__normal_iterator<unsigned char const*, _Container> operator++(int);
     __gnu_cxx::__normal_iterator<unsigned char const*, _Container> & operator--(void);
     __gnu_cxx::__normal_iterator<unsigned char const*, _Container> operator--(int);
     reference operator[](difference_type) const;
     __gnu_cxx::__normal_iterator<unsigned char const*, _Container> & operator+=(difference_type);
     __gnu_cxx::__normal_iterator<unsigned char const*, _Container> operator+(difference_type) const;
     __gnu_cxx::__normal_iterator<unsigned char const*, _Container> & operator-=(difference_type);
    __gnu_cxx::__normal_iterator<unsigned char const*, _Container> operator-(difference_type) const;

     const unsigned char * const& base(void) const;
     void __normal_iterator<unsigned char*>(const
                        __gnu_cxx::__normal_iterator<unsigned char*, _Container> &);

     typedef std::iterator_traits<unsigned char const*>::reference reference;
     typedef _Iterator pointer;
     typedef std::iterator_traits<unsigned char const*>::difference_type difference_type;
     typedef std::iterator_traits<unsigned char const*>::iterator_category iterator_category;
 }
于 2019-11-06T14:10:25.623 に答える