这是对我之前帖子的复述,因为我更改了问题(因此它可能没有被标记为新问题而被遗漏)。我也希望把它剪下来。
我有这样的功能:
#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)... );
}
whereremove_some_extents
是一个自定义类模板,就像调用std::remove_extent
元函数给定次数一样。
当我尝试运行该程序时,我遇到了一堆错误,例如:“从类型Whatever(&)[X][Y]
的表达式中对类型的引用进行无效初始化Whatever(*)[Y]
”(或Whatever(&)[Z]
从Whatever*
)。我的解决方法是将条件表达式转换为if
-else
对(并删除constexpr
)。
我试图找出问题所在,所以我在 C++ (2011) 标准中关于条件运算符的部分进行了讨论。这是第 5.16 节。当两个可能的操作之一是 throw 命令(或者是void
表达式)时,条件具有另一个表达式的类型,但标准转换(包括数组到指针)将应用于该另一个表达式。(这在第 2 段中。)我认为这让我很困惑。有什么办法吗?我认为返回数组引用会抑制 a-to-p 转换。为什么它在制成时起作用if/else
?