C++模板专门化、decltype、const类型和std::remove_const

cig3rfwq  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(112)

我一直试图找到一种方法来检查一个变量是否是一个std::array在编译时。我发现下面的线程似乎是这样做的:How to check if a type is a specialization of the std::array class template
然而,我得到了一些奇怪的结果与const std::array s有关。请参见以下示例:

#include <array>

template<typename>
struct is_std_array : std::false_type {};

template<typename T, std::size_t N>
struct is_std_array<std::array<T,N>> : std::true_type {};

std::array<int, 5> nonConstArray = {};
const std::array<int, 5> constArray = {};
constexpr std::array<int, 5> constExprArray = {};

// succeeds - makes sense
static_assert(is_std_array<std::array<int, 5>>::value, "Assertion 1."); 

// also succeeds
static_assert(is_std_array<decltype(nonConstArray)>::value, "Assertion 2."); 
// fails - ??? (how does remove_const affect this when this passed before?)
static_assert(is_std_array<std::remove_const<decltype(nonConstArray)>>::value, "Assertion 3."); 

// fails - ??? - maybe because type is const?
static_assert(is_std_array<decltype(constArray)>::value, "Assertion 4."); 
// fails - ??? - shouldn't the type with const removed work?
static_assert(is_std_array<std::remove_const<decltype(constArray)>>::value, "Assertion 5.");

// fails
static_assert(is_std_array<decltype(constExprArray)>::value, "Assertion 6."); 
// fails
static_assert(is_std_array<std::remove_const<decltype(constExprArray)>>::value, "Assertion 7.");

在我看来,Assert3、5和7应该通过。也可能是4和6。有人能解释一下为什么这些失败吗?

8oomwypt

8oomwypt1#

有人能解释一下为什么这些失败吗?
基本上,因为你没有使用后缀_t,你得到了一个类类型,比如std::remove_const<...>,它不同于类类型std::array<...>
让我们看一个例子。

static_assert(is_std_array<std::remove_const<decltype(nonConstArray)>>::value, "Assertion 3.");

这里decltype(nonConstArray)给了我们std::array<int, 5>类型,所以std::remove_const<decltype(nonConstArray)>也是一个类类型std::remove_const<std::array<int, 5> >,它将在下一个测试is_std::array中失败。

解决方案

要实际获取std::array<...>类类型,您需要访问/* 使用类型成员 *,方法是将后缀_t添加到std::remove_const,如下所示。

//------------------------------------------vv-------> this _t suffix has been added 
static_assert(is_std_array<std::remove_const_t<decltype(nonConstArray)>>::value, "Assertion 3.");

你的其他例子也是如此。

相关问题