如何将 type_traits is_same 用于 std::array
How to use type_traits is_same for std::array
我正在尝试为模板输入编写一个验证方法,它测试输入是 std::string
、std::vector
还是 std::array
。
但是对于后者,我遇到了一个问题,因为我必须为
类型定义。
所以当我调用 std::is_same<T, std::array<uint8_t, container.size()>>::value
时,编译器会生气(container.size() 不是静态的)。有办法解决这个问题吗?
我事先不知道容器的大小,我永远不会知道:(
template<typename T> bool valid_container_type(const T& container)
{
(void) container;
if constexpr (std::is_same<T, std::vector<uint8_t>>::value)
{
return true;
}
else if constexpr (std::is_same<T, std::vector<char>>::value)
{
return true;
}
else if constexpr (std::is_same<T, std::array<char, container.size()>>::value)
{
return true;
}
else if constexpr (std::is_same<T, std::array<uint8_t, container.size()>>::value)
{
return true;
}
else if constexpr (std::is_same<T, std::string>::value)
{
return true;
}
return false;
}
问题是 container.size()
不是常量表达式,不能用作非类型模板参数。
您可以添加类型特征以在编译时获取大小(或使用 std::tuple_size
directly as @康桓瑋 )。例如
template <typename>
struct get_array_size;
template <typename T, size_t S>
struct get_array_size<std::array<T, S>> {
constexpr static size_t size = S;
};
然后将其用作:
if constexpr (std::is_same<T, std::array<uint8_t, get_array_size<T>::size>>::value)
请注意,您必须将 std::string
的 if
分支移到 std::array
之前的分支。否则你也需要在主模板中定义 size
(并给它一个默认值)。
您可以检查某些 T
是否是具有 uint8_t
类型元素的 std::arary
,如下所示:
#include <iostream>
#include <array>
#include <type_traits>
template <typename T>
struct is_uint8_t_array : std::false_type {};
template <size_t S>
struct is_uint8_t_array< std::array<uint8_t,S> > : std::true_type {};
int main() {
std::cout << is_uint8_t_array<std::array<uint8_t,32>>::value << "\n"; // 1
std::cout << is_uint8_t_array<std::array<int,42>>::value << "\n"; // 0
std::cout << is_uint8_t_array<int>::value << "\n"; // 0
}
我正在尝试为模板输入编写一个验证方法,它测试输入是 std::string
、std::vector
还是 std::array
。
但是对于后者,我遇到了一个问题,因为我必须为
类型定义。
所以当我调用 std::is_same<T, std::array<uint8_t, container.size()>>::value
时,编译器会生气(container.size() 不是静态的)。有办法解决这个问题吗?
我事先不知道容器的大小,我永远不会知道:(
template<typename T> bool valid_container_type(const T& container)
{
(void) container;
if constexpr (std::is_same<T, std::vector<uint8_t>>::value)
{
return true;
}
else if constexpr (std::is_same<T, std::vector<char>>::value)
{
return true;
}
else if constexpr (std::is_same<T, std::array<char, container.size()>>::value)
{
return true;
}
else if constexpr (std::is_same<T, std::array<uint8_t, container.size()>>::value)
{
return true;
}
else if constexpr (std::is_same<T, std::string>::value)
{
return true;
}
return false;
}
问题是 container.size()
不是常量表达式,不能用作非类型模板参数。
您可以添加类型特征以在编译时获取大小(或使用 std::tuple_size
directly as @康桓瑋
template <typename>
struct get_array_size;
template <typename T, size_t S>
struct get_array_size<std::array<T, S>> {
constexpr static size_t size = S;
};
然后将其用作:
if constexpr (std::is_same<T, std::array<uint8_t, get_array_size<T>::size>>::value)
请注意,您必须将 std::string
的 if
分支移到 std::array
之前的分支。否则你也需要在主模板中定义 size
(并给它一个默认值)。
您可以检查某些 T
是否是具有 uint8_t
类型元素的 std::arary
,如下所示:
#include <iostream>
#include <array>
#include <type_traits>
template <typename T>
struct is_uint8_t_array : std::false_type {};
template <size_t S>
struct is_uint8_t_array< std::array<uint8_t,S> > : std::true_type {};
int main() {
std::cout << is_uint8_t_array<std::array<uint8_t,32>>::value << "\n"; // 1
std::cout << is_uint8_t_array<std::array<int,42>>::value << "\n"; // 0
std::cout << is_uint8_t_array<int>::value << "\n"; // 0
}