1

タプルを扱うデータ構造を操作しようとしていますが、値のインデックスに応じて取得されたデータをグローバル データ構造から実際に抽出する「タプル」を作成する必要があります。これまでのところ、この単純なセットアップでかなりうまく機能しています。

struct PseudoTuple
{
 struct ReturnWrapper
 {
  //lots of operator overloads and fun stuff for comparisons
 }

 typedef ReturnWrapper value_type;

 //pointers to global data and various info

 static const size_t size = 9;

 ReturnWrapper operator[](int index)
 {
  switch (index)
  {
   //routing to different values
  }
 }
}

template<> struct std::tr1::tuple_size<PseudoTuple>
{
 static const size_t value = PseudoTuple::size;
}

ただし、これらの偽のタプルを供給しているデータ構造は使用したいのでstd::tr1::get、それをオーバーロードしようとして失敗しました:

template<int _Idx> PseudoTuple::ReturnWrapper std::tr1::get(PseudoTuple& pseudotuple)
{
 return pseudotuple[_Idx];
}

「既存の関数宣言と一致しない」と言っています。STL 宣言は非常に紛らわしく、何が問題なのかわかりません。これは Visual C++ 2010 にあります。他のタプル固有の関数も呼び出されるのではないかと心配していますが、機能する方法を見てget、それらも機能させる方法を教えてくれることを願っています (必要な場合)。

編集: ecatmur は、名前空間に関数を配置することを提案しました:

namespace std
{
 namespace tr1
 {
  template<int _Idx> PseudoTuple::ReturnWrapper get(PseudoTuple& pseudotuple)
  {
   return pseudotuple[_Idx];
  }
 }
}

適切な get 関数がなかったときに、以前に発生したエラーが発生しています。

error C2784: '_Arg_traits<_Get<_Idx,tuple<_Arg0,_Arg1,_Arg2,_Arg3,_Arg4,_Arg5,_Arg6,_Arg7,_Arg8,_Arg9>::_MyImpl>::_Type>::_RType std::tr1::get(std::tr1::tuple<_Arg0,_Arg1,_Arg2,_Arg3,_Arg4,_Arg5,_Arg6,_Arg7,_Arg8,_Arg9> &)' : could not deduce template argument for 'std::tr1::tuple<_Arg0,_Arg1,_Arg2,_Arg3,_Arg4,_Arg5,_Arg6,_Arg7,_Arg8,_Arg9> &' from 'const PseudoTuple'

編集 2: ああ、定義の順序が間違っています。使用後に関数を定義しています。tuple_size関数ではなく、構造体のようなものでは機能すると思います。

4

1 に答える 1

0

無料の関数をオーバーロードするには、適切な名前空間で定義を提供する必要があります。

namespace std {
    namespace tr1 {
        template<int _Idx> PseudoTuple::ReturnWrapper get(PseudoTuple& pseudotuple)
        {
            return pseudotuple[_Idx];
        }
        template<int _Idx> ... get(const PseudoTuple &pseudotuple)
        {
            return ...;
        }
        template<int _Idx> ... get(PseudoTuple &&pseudotuple)
        {
            return ...;
        }
    }
}

これは17.6.4.2.1 [namespace.std] による未定義の動作であることに注意してください。名前空間に追加できる、stdまたは名前空間に含まれている唯一のコード オブジェクトは、ユーザー定義クラスのテンプレートの特殊化です。ただし、すべての引数はユーザー定義型であり、標準定義のコード オブジェクトと競合しないため、現在の標準では問題ありません。

于 2012-09-26T15:55:13.007 に答える