C++11 你能在条件表达式中抛出吗?(was:如何将边界检查扩展到多个维度?)
注意:我解决了原来的问题,实现了一个完全不同的问题。有关新的实际问题,请参见附录,但您可以阅读上一部分了解上下文 这是我的一本书的延伸。我根据这个答案创建了一个容器类:C++11 你能在条件表达式中抛出吗?(was:如何将边界检查扩展到多个维度?),c++11,multidimensional-array,conditional-operator,indexoutofboundsexception,throw,C++11,Multidimensional Array,Conditional Operator,Indexoutofboundsexception,Throw,注意:我解决了原来的问题,实现了一个完全不同的问题。有关新的实际问题,请参见附录,但您可以阅读上一部分了解上下文 这是我的一本书的延伸。我根据这个答案创建了一个容器类: template < typename T, unsigned N0, unsigned ...N > struct array_md { // There's a class template specialization with no extents. // Imagine the vario
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;
};
(删除某些扩展数据块会按照它所说的做,而不仅仅是C++11标准库提供的一个或所有扩展数据块。)
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 )...);
}
//...
};
谢谢
编辑:为选中的\u切片添加了基本大小写和r值重载
附录:我得到了一些有效的方法,但我不知道为什么旧方法不起作用
我首先注释掉了checked\u slice
的r值重载,以减少必须处理的变量。然后我制作了一个适用于标准容器的checked\u 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
内联常量表达式
自动检查\u切片(E&E,T&T)[N],标准::大小\u T u,V&…V)
->typename删除某些扩展数据块::type&
{
返回选中的切分(静态切分(e),静态切分(t[u]),
静态铸造(v);
}
i、 我删除了实际测试和失败部分的抛出,代码工作了!问题似乎不是索引,而是抛出和/或条件!果然,当我将其更改为:
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;
}
template
内联
自动检查\u切片(E&E,T&T)[N],标准::大小\u T u,V&…V)
->typename删除某些扩展数据块::type&
{
if(u
它仍然有效!我认为使用throw语句作为条件表达式的动作部分是可以的?这是我的编译器中的错误吗
我可能不得不放弃并将边界检查分离为纯函数,并在at
方法中抛出失败。由于我更改了此问题,它可能没有被标记为新问题。我从重新询问中得到了帮助,而且成功了
// 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.
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;
}