1

の実装を書いていますがzip、ちょっとした問題に遭遇しました。最小限のテスト ケースを次に示します。

#include <iostream>
#include <deque>
#include <tuple>
#include <string>
#include <limits>

template <template <typename...> class Container, typename... Types>
Container<std::tuple<Types...>> zip(Container<Types> const&... args) {
  unsigned len = commonLength(args...);
  Container<std::tuple<Types...>> res;
  std::tuple<Types...> item;

  for (unsigned i=0; i<len; i++) {
    item = getTupleFrom(i, args...);
    res.push_back(item);
  }

  return res;
}

template <class ContainerA, class... Containers>
unsigned commonLength(ContainerA first, Containers... rest, unsigned len=std::numeric_limits<unsigned>::max()) {
  unsigned firstLen = first.size();
  if (len > firstLen) {
    len = firstLen;
  }
  return commonLength(rest..., len);
}

template <class ContainerA>
unsigned commonLength(ContainerA first, unsigned len=std::numeric_limits<unsigned>::max()) {
  unsigned firstLen = first.size();
  if (len > firstLen) {
    len = firstLen;
  }
  return len;
}

template <template <typename...> class Container, typename TypeA, typename... Types>
std::tuple<TypeA, Types...> getTupleFrom(unsigned index, Container<TypeA> const& first, Container<Types> const&... rest) {
  return std::tuple_cat(std::tuple<TypeA>(first[index]), getTupleFrom(index, rest...));
}

template <template <typename...> class Container, typename TypeA>
std::tuple<TypeA> getTupleFrom(unsigned index, Container<TypeA> const& first) {
  return std::tuple<TypeA>(first[index]);
}

int main() {

  std::deque<int> test1 = {1, 2, 3, 4};
  std::deque<std::string> test2 = {"hihi", "jump", "queue"};
  std::deque<float> test3 = {0.2, 8.3, 7, 123, 2.3};
  for (auto i : zip(test1, test2, test3)) {
    std::cout << std::get<0>(i) << std::get<1>(i) << std::get<2>(i) << std::endl;
  }
  //expected output:
  //1hihi0.2
  //2jump8.3
  //3queue7
  return 0;
}

コンパイルすると、次のエラーが発生します。

error: no matching function for call to ‘commonLength(const Star::List<int>&, const Star::List<std::basic_string<char> >&, const Star::List<float>&)’
note: candidates are:
note: template<class ContainerA, class ... Containers> unsigned int Star::commonLength(ContainerA, Containers ..., unsigned int)
note: template<class ContainerA> unsigned int Star::commonLength(ContainerA, unsigned int)

テンプレートパラメーターを間違って指定していると思います。また、その関数を完全に再構築して削除しようとしましたが、 に対して同じエラーが発生しgetTupleFromます。

なぜ私がバカなのか誰か説明してくれませんか? 自分が何を間違っているのかさっぱりわからないからです。:(

4

2 に答える 2

3

さて、これはうまくいきます:

#include <iostream>
#include <deque>
#include <tuple>
#include <string>
#include <type_traits>
#include <algorithm>
#include <limits>

template <class ContainerA>
unsigned commonLength(unsigned len, const ContainerA &first) {
  unsigned firstLen = first.size();
  if (len > firstLen) {
    len = firstLen;
  }
  return len;
}


template <class ContainerA, class... Containers>
unsigned commonLength(unsigned len, const ContainerA &first, const Containers&... rest) {
  unsigned firstLen = first.size();
  if (len > firstLen) {
    len = firstLen;
  }
  return commonLength(len, rest...);
}

template <template <typename...> class Container, typename TypeA>
std::tuple<TypeA> getTupleFrom(unsigned index, Container<TypeA> const& first) {
  return std::tuple<TypeA>(first[index]);
}

template <template <typename...> class Container, typename TypeA, typename... Types>
std::tuple<TypeA, Types...> getTupleFrom(unsigned index, Container<TypeA> const& first, Container<Types> const&... rest) {
  return std::tuple_cat(std::tuple<TypeA>(first[index]), getTupleFrom(index, rest...));
}

template <template <typename...> class Container, typename... Types>
Container<std::tuple<Types...>> zip(Container<Types> const&... args) {
  unsigned len = commonLength(std::numeric_limits<unsigned>::max(), args...);
  Container<std::tuple<Types...>> res;
  std::tuple<Types...> item;

  for (unsigned i=0; i<len; i++) {
    item = getTupleFrom(i, args...);
    res.push_back(item);
  }

  return res;
}

int main() {

  std::deque<int> test1 = {1, 2, 3, 4};
  std::deque<std::string> test2 = {"hihi", "jump", "queue"};
  std::deque<float> test3 = {0.2, 8.3, 7, 123, 2.3};
  for (auto i : zip(test1, test2, test3)) {
    std::cout << std::get<0>(i) << std::get<1>(i) << std::get<2>(i) << std::endl;
  }
  //expected output:
  //1hihi0.2
  //2jump8.3
  //3queue7
}

それはあなたが期待したものを正確に出力します。問題は次のとおりです。

  • const&でコンテナを使用していませんでしたがcommonLengthzipconst の引数が参照されています。
  • の unsigned パラメータはcommonLength推定できないので、先頭に移動しました
  • 関数を間違った順序で宣言/定義したため (A には B が必要でしたが、A は B の前に定義されていました)、順序を変更しました。

どうやらclang 3.1はでテンプレート引数を推測できませんzipでしたが、g++ 4.6はそれらをうまく取得します。

于 2012-07-09T15:08:00.973 に答える
1

ステップバイステップでピッキング。

ヘッダーがありません:

#include <limits>

宣言されていない識別子があります:

template <template <typename...> class Container, typename TypeA, typename... Types>
std::tuple<TypeA, Types...> getTupleFrom(unsigned index, Container<TypeA> const& first, Container<Types> const&... rest) {
  return std::tuple_cat(std::tuple<TypeA>(first[index]), getTupleFrom(index, rest...), end);
}

どこでend宣言されますか?

一貫性がありません:

Container<std::tuple<Types...>> zip(Container<Types> const&... args) {
  unsigned len = commonLength(args...);
  Container<std::tuple<Types...>> res;

それContainer<std::tuple<Types...>>ですかContainer<Types>?それとも、これはまさにあなたが意味することですか?コードは、簡単に確認するために少し複雑です。

次に、getTupleFromゼロ以外のカウントののバージョンのみがありますContainer<TypeA>

template <template <typename...> class Container, typename TypeA, typename... Types>
std::tuple<TypeA, Types...> getTupleFrom(unsigned index, Container<TypeA> const& first, Container<Types> const&... rest) {
  return std::tuple_cat(std::tuple<TypeA>(first[index]), getTupleFrom(index, rest...), end);
}

template <template <typename...> class Container, typename TypeA>
std::tuple<TypeA> getTupleFrom(unsigned index, Container<TypeA> const& first) {
  return std::tuple<TypeA>(first[index]);
}

これがエラーが発生する理由です

error: no matching function for call to ‘getTupleFrom(unsigned int&)’

これは、引数リストが空になるポイントに何らかの理由で到達したことを示します(符号なし整数引数を除く)。私はあなたがこれを防ぐ必要があると思います。

于 2012-07-09T14:50:35.773 に答える