我有一个模板化的函数,我希望static_assert
它的类型大小为3。这段代码说明了我正在尝试做什么,但不起作用:
template < typename T >
void foo( T& param )
{
// This line is the one that I need to figure out how to write
static_assert( 3 == std::extent< T >::value, "param must have a size of 3" );
}
int main( void )
{
int cArray[3];
std::array< int, 3 > stdArray;
foo( cArray );
foo( stdArray );
}
答案 0 :(得分:9)
std::extent
是为内置数组定义的。对于std::array
,请改用std::tuple_size
。我不知道某些特性对两者都有效,但写一个很容易:
template<typename T>
struct array_size : std::extent<T> { };
template<typename T, size_t N>
struct array_size<std::array<T,N> > : std::tuple_size<std::array<T,N> > { };
并在此foo
,更正/概括(live example):
template < typename T >
void foo( T&& param )
{
using U = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
static_assert( 3 == array_size<U>::value, "param must have a size of 3" );
}
首选通用引用T&& param
,否则只能使用左值。
答案 1 :(得分:2)
这基于iavr的解决方案。
template < typename T >
void foo( T& param )
{
static_assert( 3 == ( std::is_array< T >::value ? std::extent< T >::value : std::tuple_size< T >::value ), "param must have a size of 3" );
}
答案 2 :(得分:1)
我想不出一种编写处理两者的单一函数的方法,但这就是重载的目的。
template <std::size_t N, typename T, std::size_t Bound>
void check_array_size( T (&)[Bound] )
{
static_assert(Bound == N, "incorrect array size");
}
template <std::size_t N, typename T, std::size_t Bound>
void check_array_size( const std::array<T,Bound>& )
{
static_assert(Bound == N, "incorrect array size");
}
template <std::size_t N>
void check_array_size( ... )
{
static_assert(N<0, "argument is not an array");
}
template <typename T>
void foo(T& param)
{
check_array_size<3>(param);
// actual function implementation...
}
答案 3 :(得分:0)
我怀疑你有这个错误,因为在编译时(评估* static_assert *时) cArray 和 stdArray 的维度是未知的,并且< em> std :: extent 返回零:
http://en.cppreference.com/w/cpp/types/extent
实际上,如果将条件更改为等于零,则错误消失:
static_assert( std::extent< T >::value == 0, "param is not zero" );
然而,正如其他帖子中已经指出的那样, std :: extent 对于 std :: array 不起作用,仅适用于内置数组as cArray
OP的编辑后: 既然您已经修改了 foo 来接受引用,那么 cdrray 和0(零)的 std :: extent 报告3对于 stdArray 。因此,您将在编译时继续执行异常,因为 stdArray 的维度不是3。