C ++ - タイプVS定数パラメーターのタプルと解像度を繰り返す
質問
私は現在、タプル用の算術演算子の過負荷を書く過程にあります。オペレーターはタプルを繰り返して、個々の要素のそれぞれで操作を実行します。これがオペレーター +=の定義です。
template< typename... Ts, std::size_t I = 0 >
inline typename std::enable_if< I == sizeof... (Ts), std::tuple< Ts... >& >::type operator +=(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
return lhs;
}
template< typename... Ts, std::size_t I = 0 >
inline typename std::enable_if< I != sizeof... (Ts), std::tuple< Ts... >& >::type operator +=(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
std::get< I >(lhs) += std::get< I >(rhs);
return operator +=< Ts..., I + 1 >(lhs, rhs);
}
残念ながら、オペレーターに電話をかけようとすると、GCC 4.6が使用する過負荷を決定できません。例えば:
std::tuple< int, int, int, int > a = std::make_tuple(1, 2, 3, 4), b = std::make_tuple(5, 6, 7, 8);
a += b;
次のエラーが生成されます。
:/Workspace/raster/main.cpp:833:7: instantiated from here
C:/Workspace/raster/main.cpp:809:45: error: no matching function for call to 'operator+=(std::tuple<int, int, int, int>&, const std::tuple<int, int, int, int>&)'
C:/Workspace/raster/main.cpp:809:45: note: candidates are:
C:/Workspace/raster/main.cpp:800:151: note: template<class ... Ts, unsigned int I> typename std::enable_if<(I == sizeof (Ts ...)), std::tuple<_TElements ...>&>::type operator+=(std::tuple<_TElements ...>&, const std::tuple<_TElements ...>&)
C:/Workspace/raster/main.cpp:806:83: note: template<class ... Ts, unsigned int I> typename std::enable_if<(I != sizeof (Ts ...)), std::tuple<_TElements ...>&>::type operator+=(std::tuple<_TElements ...>&, const std::tuple<_TElements ...>&)
それ以来奇妙です std::enable_if
条件は不適切な呼び出しを拒否する必要があります。今のところ、私は実際に私の以前の実装であった次の回避策を持っています。上記のバージョンは、実際には単純化の試みです。
template< std::size_t I, typename... Ts >
inline typename std::enable_if< I == sizeof... (Ts), std::tuple< Ts... >& >::type assignadd_impl(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
return lhs;
}
template< std::size_t I, typename... Ts >
inline typename std::enable_if< I != sizeof... (Ts), std::tuple< Ts... >& >::type assignadd_impl(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
std::get< I >(lhs) += std::get< I >(rhs);
return assignadd_impl< I + 1, Ts... >(lhs, rhs);
}
template< typename... Ts >
inline std::tuple< Ts... >& operator +=(std::tuple< Ts... >& lhs, const std::tuple< Ts... >& rhs)
{
return assignadd_impl< 0, Ts... >(lhs, rhs);
}
これは、期待どおりにコンパイルして機能します。単純化されたバージョンがコンパイルを拒否するのはなぜですか?ありがとう。
解決
明示的に指定されたテンプレート引数を関数またはクラステンプレートに使用するには、テンプレートパラメーター全体のパラメーターパックが全体的なパラメーターリストの最後に表示される必要があります。動く Ts...
テンプレートパラメーターリストの最後まで、呼び出しを適切に変更すると、コードが機能します。セクション14.8.2.1 of 現在のC ++ 0xドラフト テンプレートパラメーターリストの最後にないパラメーターパックは、関数呼び出し(元のコードに失敗させる)から推定できないが、すべてのテンプレート引数を明示的に指定することはできないと述べています。 operator+=
すべての場合、依然としてsfinaeエラーが発生します。 前の質問 それを禁止する正確なテキストへのリンクがあります。 IBMのドキュメント エラーでもあると言います。
所属していません StackOverflow