如何获取向量中元素的类型?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何获取向量中元素的类型?相关的知识,希望对你有一定的参考价值。
考虑模板元编程技术,如果我有
std::vector<int> v;
v.push_back(42.42f);
这工作,主要是因为使用它的构造函数没有标记explicit
,换句话说我的push_back
它不是类型安全的。
现在我处在一种我甚至不知道如何声明容器v
的情况,在这种情况下它是int
,但我需要在拥有通用std::vector<T>
时自动推断出类型。我想要一个解决方案来获得T
。
在C ++ 11中有类似remove_all_extents
(有一个有用的成员type
),但显然它只对旧数组有用,但它基本上是我想要实现的。
我想在push_back
它不是类型安全或推断类型时触发错误,所以我可以写一个断言或自己实现一些东西。
我真的找不到一个有效的解决方案,它在理论上如此简单,但是一旦声明了一个向量,就没有关于用于元素的类型的明确信息。
我也想避免明确的类型推断,比如从我理想的函数调用中翻译foo
foo( container, elements ... )
至
foo<int>(container, elements ...)
其中int
是container
元素的类型,在我看来这也不安全,它也更冗长,更容易出错。
那么如何在C ++ 11中检索容器元素的类型呢?
你可以得到这样的类型:
typename std::vector<T>::value_type;
然后使用static_assert
和std::is_same
。
template <typename T1, typename T2>
void special_push_back(std::vector<T1>& v, T2 elem)
{
// check that T1 and T2 are the same before pushing elem into v
}
然后
std::vector<int> v;
special_push_back(v, 3.14); // Compile time error: double is not int
如果您有C ++ 11功能,还可以使用decltype
关键字来轻松访问value_type
:
decltype(TheContainer)::value_type nVarOfType;
其中TheContainer
可能是任何类型的容器。例如map<int, string>
,deque<float>
或任何其他STL容器,因为所有STL容器都具有value_type
类型定义。 decltype
将返回给定对象的类型。
如果我理解正确的评论,您也可以尝试:
template <class Container, class... Args>
void foo(Container&& c, Args&&... args) {
typedef typename Container::value_type value_type;
// use type_traits to check value_type
...
}
一个改进是检查Container
是否有嵌入式value_type
:
template <class T>
struct has_value_type
{
private:
template <class U> static std::false_type test(...);
template <class U> static std::true_type test(typename U::value_type*);
public:
enum { value = decltype(test<T>(0))::value };
};
然后使用std::enable_if
:
template <class Container, class... Args>
typename std::enable_if<has_value_type<Container>::value, return_type>::type
foo(Container&& c, Args&&... args) {
typedef typename Container::value_type value_type;
...
}
同样,您只能“启用”满足您对值类型要求的模板:
template <class Container, class... Args>
typename std::enable_if<
has_value_type<Container>::value
and std::is_same<int, typename Container::value_type>::value
>::type
foo2(Container&& c, Args&&... args) {
typedef typename Container::value_type value_type;
// here value_type equals int
}
编辑:
通过更多“模板技巧”,您可以确保所有类型的可变参数模板包都相等,并且等于容器的value_type:
首先,帮助模板:
template <typename...>
struct all_of;
template <typename T>
struct all_of<T> : std::conditional<T::value == true,
std::true_type, std::false_type>::type
{};
template <typename Head, typename... Tail>
struct all_of<Head, Tail...> : std::conditional<
Head::value == true and all_of<Tail...>::value,
std::true_type,
std::false_type>::type
{};
没有任何进一步的代码,您可以使用它,例如,如下所示:
`all_of<std::is_nothrow_copy_constructible<Args>...>::value`
虽然语法可能看起来很奇怪,但如果参数包true
中的所有类型都具有其拷贝构造函数不会抛出的属性,则上面的const表达式将计算为Args
。
给定辅助类模板all_of
,只有当参数包中的所有类型都等于容器的foo
时,我们才能启用函数模板value_type
:
template <class Container, class... Args>
typename std::enable_if<
has_value_type<Container>::value
and all_of<std::is_same<typename Container::value_type, Args>...>::value
>::type
foo2(Container&& c, Args&&... args) {
typedef typename Container::value_type value_type;
// here *all* types in Args are equal value_type
}
以上是关于如何获取向量中元素的类型?的主要内容,如果未能解决你的问题,请参考以下文章