Как массив может работать с условным оператором?

Это пересказ мой предыдущий пост, так как я изменил вопрос (так что он, вероятно, не был помечен как новый вопрос и был пропущен). Надеюсь, я тоже урежу это.

У меня были такие функции, как:

#include <cstddef>
#include <type_traits>

template < typename E, typename T >
inline constexpr
auto  checked_slice( E &&, T &&t ) noexcept -> T &&
{ return static_cast<T &&>(t); }

template < typename E, typename T, std::size_t N, typename U, typename ...V >
inline constexpr
auto  checked_slice( E &&e, T (&t)[N], U &&u, V &&...v )
-> typename remove_some_extents<T, sizeof...(V)>::type &
{
typedef typename std::remove_reference<U>::type                 u_type;
typedef typename std::common_type<u_type, std::size_t>::type  cmp_type;

return ( u < u_type{} ) || ( static_cast<cmp_type>(u) >=
static_cast<cmp_type>(N) ) ? throw e : checked_slice( static_cast<E &&>(e),
t[static_cast<U &&>( u )], static_cast<V &&>(v)... );
}

где remove_some_extents это пользовательский шаблон класса, который походит на вызов std::remove_extent мета-функция заданное количество раз.

Когда я попытался запустить программу, я получил кучу ошибок, таких как: «неверная инициализация ссылки типа Whatever(&)[X][Y] из выражения типа Whatever(*)[Y]» (или же Whatever(&)[Z] от Whatever*). Мой обходной путь должен был преобразовать условное выражение в ifelse пара (и удаление constexpr).

Я пытаюсь выяснить, что не так, поэтому я изучаю раздел об условном операторе в стандарте C ++ (2011). Это раздел 5.16. Когда одним из двух возможных действий является команда броска (или void выражением), тогда условное выражение имеет тип другого выражения, но к этому другому выражению применяются стандартные преобразования, в том числе массив-указатель. (Это в параграфе 2.) Я думаю, это то, что меня портит. Есть ли способ обойти это? Я думал, что возвращение ссылки на массив подавляет преобразование a-to-p. Почему это работает, когда превращается в if/else?

3

Решение

Ваш анализ верен. Я подозреваю, что неvoid операнд «распадается» (то есть выполняются обычные преобразования) в такой ситуации, чтобы имитировать то, что происходит, когда два операнда различаются по типам — в последнем случае чаще всего целое условное выражение является prvalue.

Одна ситуация, в которой мы точно знаем и категорию значения, и тип условного выражения, — это когда два операнда являются точными совпадениями, поэтому мы можем использовать это в наших интересах:

cond ? (throw e, t) : t

будет lvalue ссылочного типа массива. (Конечно, последний операнд не должен быть буквально t — Вы можете подключить свой рекурсивный вызов здесь просто отлично.)

Вы не сталкивались с таким препятствием при использовании if/else потому что в качестве утверждения язык не должен указывать общий тип и категорию значений для него.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]