質問を変更したため、これは以前の投稿の再話です(そのため、おそらく新しい質問としてフラグが立てられず、見逃されました)。うまくいけば、私もそれをトリミングします。
次のような機能がありました:
#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)... );
}
whereは、メタ関数を特定の回数remove_some_extents
呼び出すようなカスタム クラス テンプレートです。std::remove_extent
Whatever(&)[X][Y]
プログラムを実行しようとすると、「型の式からの型の参照の初期化が無効ですWhatever(*)[Y]
」(またはWhatever(&)[Z]
からWhatever*
)のような一連のエラーが発生しました。if
私の回避策は、条件式を-else
ペアに変換することでした(そして を削除しますconstexpr
)。
何が問題なのかを突き止めようとしているので、C++ (2011) 標準の条件演算子に関するセクションを調べています。それがセクション 5.16 です。2 つの可能なアクションの 1 つが throw コマンド (またはそれ以外の場合はvoid
式) である場合、条件は他の式の型を持ちますが、配列からポインターへの変換を含む標準の変換がその他の式に適用されます。(これは段落 2 にあります。) それが私をめちゃくちゃにしていると思います。それを回避する方法はありますか?配列参照を返すと、a-to-p 変換が抑制されると思いました。にすると機能するのはなぜif/else
ですか?