Вопрос

Я пытаюсь написать общую функцию фильтрации, которая выполняет линейную интерполяцию в данной координате выборки в многомерном массиве (произвольный ранг). Для этого мне нужен шаблон рекурсивной функции, который проходит через все измерения массива, пока он не достигнет значения и связанного с ним типа. Я использую 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, я> даже если ему указано использовать значение Test <T, I - 1>. Есть идеи, почему это поведение происходит? Пока это думает, что я просто превратит все это в функтор ...

Это было полезно?

Решение

Вопрос в том, что вы передали 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-Pehype, используемая для определения типа возврата, должна быть почти всегда такой же, как фактическое возвращение.

РЕДАКТИРОВАТЬ: Мне нужно добавить, что вы не должны передавать RValues, когда в действительности вы будете передавать LVALUE, особенно в шаблоны, так как вы вполне можете получить разные результаты.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top