2

注:まったく別の問題を実現することで、元の問題を解決しました。新しい実際の問題については補遺を参照してください。ただし、コンテキストについては前の部分を読むことができます。

これは、以前の投稿の 1 つを拡張したものです。その答えに基づいてコンテナクラスを作成しました:

template < typename T, unsigned N0, unsigned ...N >
struct array_md
{
    // There's a class template specialization with no extents.

    // Imagine the various N... components are bracket-enclosed instead
    // of comma-separated.  And if "N..." is empty, then we just have "T"
    // as the "direct_element_type".  (I actually use recursive class
    // definitions.)
    using direct_element_type = T[N...];
    using data_type = direct_element_type[ N0 ];

    template < typename ...Indices >
    auto  operator ()( Indices &&...i )
    noexcept( !indexing_result<data_type &, Indices...>::can_throw )
    -> typename indexing_result<data_type &, Indices...>::type
    { return slice(data, static_cast<Indices &&>( i )...); }

    template < typename ...Indices >
    constexpr
    auto  operator ()( Indices &&...i ) const
    noexcept( !indexing_result<data_type &, Indices...>::can_throw )
    -> typename indexing_result<data_type &, Indices...>::type
    { return slice(data, static_cast<Indices &&>( i )...); }

    data_type  data;
};

atこのコンテナ用の のバージョンを作成しようとしています。slice例外オブジェクトを取るバージョンを作成するだけだと考えました。一般的な とは異なりslice、 mychecked_sliceは組み込みの配列オブジェクトを取得する必要があります。これは、ポインターとクラス型 ( を使用operator []) には境界を与える (標準的な) 方法がないためです。

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 ...V >
inline constexpr
auto  checked_slice( E &&e, T (&t)[N], std::size_t u, V &&...v )
-> typename remove_some_extents<T[N], 1u + sizeof...(V)>::type &
{
    return u < N ? checked_slice( static_cast<E &&>(e), static_cast<T &>(t[ u ]),
     static_cast<V &&>(v)... ) : throw static_cast<E &&>( e );
}

template < typename E, typename T, std::size_t N, typename ...V >
inline constexpr
auto  checked_slice( E &&e, T (&&t)[N], std::size_t u, V &&...v )
-> typename remove_some_extents<T[N], 1u + sizeof...(V)>::type &&
{
    return u < N ? checked_slice( static_cast<E &&>(e),static_cast<T &&>(t[ u ]),
     static_cast<V &&>(v)... ) : throw static_cast<E &&>( e );
}

(remove_some_extentsは、C++11 標準ライブラリが提供する 1 つまたはすべての代わりに、それが言うことを行います。) これを my に入れるとat:

template < typename T, unsigned N0, unsigned ...N >
struct array_md
{
    //...
    template < typename ...Indices >
    auto  at( Indices &&...i )
    -> typename remove_some_extents<data_type, sizeof...( Indices )>::type &
    {
        return checked_slice(std::out_of_range{ "Index out of bounds" }, data,
         static_cast<Indices &&>( i )...);
    }

    template < typename ...Indices >
    constexpr
    auto  at( Indices &&...i ) const
    -> typename remove_some_extents<data_type,sizeof...( Indices )>::type const &
    {
        return checked_slice(std::out_of_range{ "Index out of bounds" }, data,
         static_cast<Indices &&>( i )...);
    }
    //...
};

配列からポインタへの減衰に関連するエラーが発生します! (Windows-8 Pro 32ビット用のCodeBlocks 12.11にバンドルされているTDC-GCC 4.7.1を使用しています。)

In file included from container/array_md.hpp:36:0,
                 from test\arraymd_test.cpp:15:
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const int; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const int; std::size_t = unsigned int]':
container/array_md.hpp:284:112:   required from 'constexpr const typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) const [with Indices = {int}; T = int; unsigned int M = 2u; unsigned int ...N = {}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = int]'
test\arraymd_test.cpp:224:1:   required from here
utility/slice.hpp:141:10: warning: returning reference to temporary [enabled by default]
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [2][6]; std::size_t = unsigned int]':
container/array_md.hpp:284:112:   required from 'constexpr const typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) const [with Indices = {int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = char [2][6]]'
test\arraymd_test.cpp:238:1:   required from here
utility/slice.hpp:141:10: error: invalid initialization of reference of type 'const char (&)[2][6]' from expression of type 'const char (*)[6]'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [2][6]; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]':
utility/slice.hpp:141:10:   required from 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]'
container/array_md.hpp:284:112:   required from 'constexpr const typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) const [with Indices = {int, int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = char [6]]'
test\arraymd_test.cpp:239:1:   required from here
utility/slice.hpp:141:10: error: invalid initialization of reference of type 'const char (&)[6]' from expression of type 'const char*'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]':
container/array_md.hpp:284:112:   required from 'constexpr const typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) const [with Indices = {int, int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = char [6]]'
test\arraymd_test.cpp:239:1:   required from here
utility/slice.hpp:141:10: error: invalid initialization of reference of type 'const char (&)[6]' from expression of type 'const char*'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {unsigned int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]':
container/array_md.hpp:284:112:   required from 'constexpr const typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) const [with Indices = {int, unsigned int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = char [6]]'
test\arraymd_test.cpp:261:5:   required from here
utility/slice.hpp:141:10: error: invalid initialization of reference of type 'const char (&)[6]' from expression of type 'const char*'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {unsigned int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = int; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = int; std::size_t = unsigned int]':
container/array_md.hpp:274:112:   required from 'typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) [with Indices = {int}; T = int; unsigned int M = 2u; unsigned int ...N = {}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = int]'
test\arraymd_test.cpp:220:1:   required from here
utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'remove_some_extents<int [2], 1u>::type& {aka int&}' from an rvalue of type 'int'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = int; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = int; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [2][6]; std::size_t = unsigned int]':
container/array_md.hpp:274:112:   required from 'typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) [with Indices = {int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = char [2][6]]'
test\arraymd_test.cpp:234:1:   required from here
utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'char (&)[2][6]' from an rvalue of type 'char (*)[6]'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [2][6]; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]':
utility/slice.hpp:141:10:   required from 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]'
container/array_md.hpp:274:112:   required from 'typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) [with Indices = {int, int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = char [6]]'
test\arraymd_test.cpp:235:1:   required from here
utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'char (&)[6]' from an rvalue of type 'char*'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]':
container/array_md.hpp:274:112:   required from 'typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) [with Indices = {int, int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = char [6]]'
test\arraymd_test.cpp:235:1:   required from here
utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'char (&)[6]' from an rvalue of type 'char*'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {long double}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]':
container/array_md.hpp:274:112:   required from 'typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type& container::array_md<T, M, N ...>::at(Indices&& ...) [with Indices = {int, long double}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents<typename container::array_md<T, N ...>::data_type [M], sizeof (Indices ...)>::type = char [6]]'
test\arraymd_test.cpp:260:5:   required from here
utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'char (&)[6]' from an rvalue of type 'char*'
utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {long double}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]' not a return-statement
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {unsigned int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [6]; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = const char [2][6]; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {long double}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [6]; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = char [2][6]; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]
utility/slice.hpp: In function 'constexpr typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type& checked_slice(E&&, T (&)[N], std::size_t, V&& ...) [with E = std::out_of_range; T = int; unsigned int N = 2u; V = {}; typename remove_some_extents<T [N], (1u + sizeof (V ...))>::type = int; std::size_t = unsigned int]':
utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type]

配列参照を使用すると、配列からポインターへの減衰がキャンセルされると思いました。これは GCC のバグですか、それともどこかを台無しにしていますか?

"slice.hpp" の場合、行 141、列 10 は関数 (の左辺値バージョン) のステートメントの終わりであり、checked_sliceL142C1 は関数の終了ブラケットです。at「array_md.hpp」では、L284C112 と L274C112 はそれぞれ関数の return (および唯一の) ステートメントであり、constconst ではありません。列は 内の「i」にありstatic_castます。

ちなみにこちらremove_some_extents

// Forward declaration
template < typename Array, std::size_t Count >
struct remove_some_extents;

// Case with indefinite array but no extents to strip
template < typename T >
struct remove_some_extents< T[], 0u >
{ typedef T type[]; };

// Case with definite array but no extents to strip
template < typename T, std::size_t N >
struct remove_some_extents< T[N], 0u >
{ typedef T type[N]; };

// Case with non-array type but no extents to strip
template < typename T >
struct remove_some_extents< T, 0u >
{ typedef T type; };

// Case with indefinite array and extents to strip
template < typename T, std::size_t L >
struct remove_some_extents< T[], L >
{ typedef typename remove_some_extents<T, L - 1u>::type type; };

// Case with definite array and extents to strip
template < typename T, std::size_t N, std::size_t L >
struct remove_some_extents< T[N], L >
{ typedef typename remove_some_extents<T, L - 1u>::type type; };

// Right now, non-array type with non-zero strip count should give an error.

ありがとう。

編集:の base-case と r-value のオーバーロードを追加しましたchecked_slice

補遺:動作するものを手に入れましたが、なぜ古い方法が動作しなかったのかわかりません。

最初に の右辺値のオーバーロードをコメントアウトして、checked_slice使用する変数を減らしました。次に、標準のコンテナで動作するバージョンを作成しましたがchecked_slice、役に立たなかったので見る必要はありません。(そして、違いがないことを確認するためにコメントアウトしました。)

通常バージョンを次のように変更しました。

template < typename E, typename T, std::size_t N, typename ...V >
inline constexpr
auto  checked_slice( E &&e, T (&t)[N], std::size_t u, V &&...v )
 -> typename remove_some_extents<T[N], 1u + sizeof...(V)>::type &
{
    return checked_slice( static_cast<E &&>(e), static_cast<T &>(t[ u ]),
     static_cast<V &&>(v)... );
}

つまり、実際のテストとスロー オン フェイルの部分を削除したところ、コードが機能しました。問題はインデックス作成ではないようでしたが、スローおよび/または条件付き! 案の定、次のように変更したとき:

template < typename E, typename T, std::size_t N, typename ...V >
inline
auto  checked_slice( E &&e, T (&t)[N], std::size_t u, V &&...v )
 -> typename remove_some_extents<T[N], 1u + sizeof...(V)>::type &
{
    if ( u < N )
        return checked_slice(static_cast<E &&>(e),t[u],static_cast<V &&>(v)...);
    else
        throw e;
}

それはまだ動作します!条件式のアクション部分の 1 つとして throw ステートメントを使用しても問題ないと思いましたか? 私のコンパイラのバグですか?

atメソッド内で境界チェックを純粋関数とスロー オン フェイルにあきらめて分離する必要があるかもしれません。

4

1 に答える 1