问题描述
限时送ChatGPT账号..我想要一个类型特征来获取 std::array
或普通旧 C 样式数组的元素类型,例如.当与 std::array
或 char[3]
一起提供时,它应该返回 char
.
I would like a type trait to get the element type of either a std::array
or a plain old C-style array, eg. it should return char
when provided with either std::array<char, 3>
or char[3]
.
执行此操作的机制似乎只是部分到位...我可以在 std::array
和 std 上使用
在普通数组上,但我找不到结合两者的单一类型特征,我无法自己编写一个.::value_type
::remove_all_extents
The mechanisms to do this appear to be only partially in place... I can use ::value_type
on the std::array
, and std::remove_all_extents
on the plain array, but I can't find a single type trait that combines both and I'm unable to write one myself.
我已经做到了:
#include <array>
#include <type_traits>
template <class T>
using element_type = typename std::conditional<
std::is_array<T>::value,
typename std::remove_all_extents<T>::type,
typename T::value_type
>::type;
它当然适用于 std::array
:
int main()
{
static_assert(
std::is_same<char, element_type<std::array<char, 3>>>::value,
"element_type failed");
}
但是当我向它传递一个普通数组时会中断,因为显然普通数组没有 ::value_type
.
but breaks when I pass it a plain array, because obviously plain arrays don't have a ::value_type
.
static_assert(std::is_same<char, element_type<char[3]>>::value, "element_type failed");
正如您所期望的那样,只会给出诸如'T':后跟 '::' 时必须是类或命名空间"之类的错误.
just gives errors like "'T': must be a class or namespace when followed by '::'", as you'd expect.
如果我正在编写一个函数,我会使用 std::enable_if
来隐藏有问题的模板实例化,但我不知道如何在类型特征中使用这种方法.
If I were writing a function, I'd use std::enable_if
to hide the offending template instantiation, but I don't see how this approach can be used in a type trait.
解决这个问题的正确方法是什么?
What is the correct way to solve this problem?
推荐答案
非常 通用的解决方案,它支持 std::begin
:
For a very generic solution which supports any type of container/array supported by std::begin
:
template<typename T>
using element_type_t = std::remove_reference_t<decltype(*std::begin(std::declval<T&>()))>;
std::begin
你可能知道返回一个迭代器.取消引用它会给你它的价值,你可以得到使用 decltype
的类型.std::remove_reference_t
是必需的,因为迭代器返回对它们指向的元素的引用.因此,这适用于 std::begin
具有重载的每种类型.
std::begin
as you may know returns an iterator. Dereferencing it gives you the value of it, which you can get the type of using decltype
. The std::remove_reference_t
is necessary because iterators return references to the element they are pointing at. As a result, this works for every single type for which std::begin
has an overload.
这篇关于输入特征以获取 std::array 或 C 样式数组的元素类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论