gpt4 book ai didi

c++ - 有没有办法确保模板参数是一个容器?

转载 作者:行者123 更新时间:2023-11-30 04:16:35 25 4
gpt4 key购买 nike

确保模板参数是容器的机制是什么?

或者,我如何根据其参数是否为容器对类/函数进行不同的特化?

最佳答案

测试一个完整的容器是困难且模糊的。就个人而言,当且仅当它拥有其直接内容时,我才将某物视为容器,但这可能与其他人对该术语的使用不一致。

测试可迭代性 既不困难也不模糊,并且通常是您在函数参数中获取对象时要测试的内容。有些可迭代的东西不是很像容器(例如 C++1y 或 C++1z 的 string_view )。

在我看来,在 C++11 中,类型 X 的实例 c 是可迭代的,当且仅当:

for( auto&& a : c ) {}

格式正确。为上面选择的措辞意味着您可以使用 begin 扩展任何类型和 end自由函数重载以使其可迭代。

如果上述方法可行,一个不错的近似是测试是否在参数依赖启用的查找上下文中 std::beginstd::end返回具有有效 std::iterator_traits<> 的内容.

作为快速草图,我得到这样的东西:

template<typename T, typename=void>
struct is_iterable : std::false_type {};

namespace aux {
using std::begin;
// note: no implementation
template<typename C>
auto adl_begin( C&& c )->decltype( begin( std::forward<C>(c) ) );
using std::end;
// note: no implementation
template<typename C>
auto adl_end( C&& c )->decltype( end( std::forward<C>(c) ) );
}
template<typename T>
struct is_iterable<T,
typename std::enable_if<
std::is_same<
typename std::iterator_traits< typename std::decay<decltype( aux::adl_begin( std::declval<T>() ) )>::type >::iterator_category,
typename std::iterator_traits< typename std::decay<decltype( aux::adl_end( std::declval<T>() ) )>::type >::iterator_category
>::value
>::type
> : std::true_type {};

Live example

与此同时,容器很少是统一的。它们最基本的“通用”过程(如添加元素)在签名和语义方面各不相同。 erase(iterator)::allocator_type是类容器结构的两个最常见的特征,但是 std::array<T,N>T[N]可以说是容器并且没有任何属性。

简而言之,除了它们的可迭代性的共同属性之外,容器差异太大以至于没有非常有用的 is_container<C>特质类。相反,您应该找出您正在寻找的容器的哪些属性(删除元素的能力?插入元素的能力?随机访问?)并测试这些属性。

关于c++ - 有没有办法确保模板参数是一个容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17684047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com