您可以在条件表达式中抛出? (是:如何能够边界检查扩展到多个维度?)(Can you throw

2019-08-31 20:55发布

注:我通过实现一个完全不同的解决原来的问题。 看到新的实际问题的附录,但你可以阅读上下文中的一个部分。

这是我的一个扩展以前的帖子 。 我做了基于这个答案的容器类:

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 ,我checked_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标准库给你。)当我把这个变成我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 )...);
    }
    //...
};

我得到与数组到指针的衰变错误! (我使用TDC-GCC 4.7.1一个与代码块12.11捆绑的Windows 8专业版32位。)

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是在(的L值版本)的语句结尾checked_slice功能,而L142C1是函数的结尾括号。 在“array_md.hpp”,L284C112和L274C112是返回(和鞋底)语句at函数, const分别和非const。 该栏中的“我”里面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.

谢谢。

编辑:增加了基本情况和R值重载checked_slice

附录:我得到了一些作品,但我不知道为什么老办法没有奏效。

我第一次注释掉的r值过载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;
}

它仍然有效! 是什么给了,我认为这是确定以使用throw语句作为条件表达式的动作部分之一? 难道是我的编译器中的错误?

我可能不得不放弃和边界检查分开,一个纯粹的功能和附着,失效内at方法。

Answer 1:

因为我改变了这个问题,它可能还没有被标记为一个新的。 我得到了一个答案 ,从重新询问在另一篇文章中 ,和它的工作。



文章来源: Can you throw within a conditional expression? (was: How can bounds-checking be extended to multiple dimensions?)