std::vector
是一个不稳定的容器,即通过调整向量大小,迭代器可能会失效。
相反,std::list
或boost::container::stable_vector
是稳定的容器,它们在删除相应元素之前保持迭代器有效。
有没有办法检查给定的容器是否稳定?例如,如果我有类似
的东西template<template <typename A, typename B=std::allocator<A> > class T=std::list>
class Foo
{
}
是否可以只允许稳定的容器并禁止不稳定的容器?
答案 0 :(得分:6)
我不认为提供此类信息有任何可用的信息,但您可以编写自己的特征。但是,您需要将其专门用于可能使用的每个稳定容器,这可能不是一种选择。
#include <boost/container/vector.hpp>
#include <iostream>
#include <type_traits>
#include <list>
#include <vector>
template <template <typename...> class Container>
struct is_stable
: std::false_type
{};
template <>
struct is_stable<std::list>
: std::true_type
{};
template <>
struct is_stable<boost::container::stable_vector>
: std::true_type
{};
template<template <typename...> class Container = std::list>
class Foo
{
static_assert(is_stable<Container>::value, "Container must be stable");
};
int main()
{
Foo<std::list> f1; // ok
Foo<std::vector> f2; // compiler error
}
我不认为有一种方法可以自动检测容器是否稳定,而不需要手动专业化。
为了好玩,我尝试写出稳定性概念/公理的样子(concepts和axioms是considered for inclusion in C++11语言的扩展名:
concept StableGroup<typename C, typename Op>
: Container<C>
{
void operator()(Op, C, C::value_type);
axiom Stability(C c, Op op, C::size_type index, C::value_type val)
{
if (index <= c.size())
{
auto it = std::advance(c.begin(), index);
op(c, val);
return it;
}
<->
if (index <= c.size())
{
op(c, val);
return std::advance(c.begin(), index);
}
}
}
如果认为这正确地捕获了对原始容器上的每个迭代器等同于修改后的容器上的相应迭代器的要求。不确定这是非常有用的,但想出这样的公理是一个有趣的练习:)!