質問

多次元配列(任意のランク)で特定のサンプリング座標で線形補間を実行する汎用フィルタリング関数を書き込もうとしています。このためには、値とそれに関連するタイプにヒットするまで、配列のすべての寸法を通過する再帰関数テンプレートが必要です。 Boost :: enable_ifを使用して、ディメンションを介して繰り返しを停止する時期を検出します。戻り値/タイプを最上位の関数に「浸透」しようとするまで、それは問題なく動作します。この目的のために、C ++ 0xタイプの推論を使用しようとしましたが、Boost :: Enable_ifとうまく混ざっていないようです。

問題を以下に分離しました。

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I == 0), typename T::value_type >::type
{
    return t[0];
}

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I > 0), decltype(test< T, I - 1 >(T())) >::type
{
    return test< typename T::value_type, std::size_t(I - 1) >(t[0]);
}

コンパイラ(GCC 4.6)は、次のコードに文句を言います。

typedef std::array< std::array< float, 1 >, 1 > myarray;
myarray ma;
std::cout << typeid (test< myarray, 1 >(ma)).name() << std::endl;

エラーメッセージ:

error: conversion from 'boost::enable_if_c<true, float>::type' to non-scalar type 'boost::enable_if_c<true, std::array<float, 1u> >::type' requested

Decltypeは、テスト<t、i -1>のそれを使用するように指示されていても、テスト<t、i>からの返品値を使用しているようです。なぜこの動作が起こるのかという考えはありますか?とりあえず、それは私がすべてを機能する人に変えるだけだと思います...

役に立ちましたか?

解決

問題は、T()(およびT)をDecltypeに渡したことです。タイプは折りたたまれていません。これは、リターン式をDecltypeに渡したものと比較すると明らかに明らかになります - それらは一貫性がありません。

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I > 0), decltype(test< T, I - 1 >(T())) >::type
{
    return test< typename T::value_type, std::size_t(I - 1) >(t[0]);
}

decltype: test<T

return expression: test< typename T::value_type

このようなフォワード関数を定義する場合、返品タイプを定義するために使用されるdecltype発現は、ほぼ常に実際の返品式とまったく同じでなければなりません。

編集:RValuesを渡すべきではないことを追加する必要があります。実際には、特にテンプレートにLValuesを渡す場合があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top