多次元配列 (任意のランク) の特定のサンプリング座標で線形補間を実行する汎用フィルタリング関数を作成しようとしています。このためには、値とそれに関連付けられた型に到達するまで、配列のすべての次元をたどる再帰関数テンプレートが必要です。ディメンションの反復処理を停止するタイミングを検出するために、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
test< T, I - 1 > の戻り値を使用するように指示されているにもかかわらず、decltype は test< T, I > の戻り値を使用しているようです。この動作が発生する理由は何ですか? 今のところ、全体をファンクターに変えるだけだと思います...