具有特定元素类型的常规可迭代类型
General iterable type with specific element type
我正在尝试编写一个函数,用于枚举特定基数的数字,其中数字存储在某种列表中。下面是一个例子,取一个 std::vector
void next_value(std::vector<unsigned int> &num, unsigned int base) {
unsigned int carry = 1;
for (unsigned int &n: num) {
n += carry;
if (n >= base) {
carry = 1;
n = 0;
} else {
carry = 0;
}
}
}
num 向量不一定是向量,它可以是一个数组,或者实际上任何定义了 std::begin() 和 std::end() 的类型。有没有办法表达 num 可以是带有 begin() 和 end() 的任何内容,但它的元素必须具有无符号的 int 类型?
如果您确实要检查这一点,请尝试:
template <class Sequence>
void next_value(Sequence &num, unsigned int base) {
static_assert(boost::is_same<Sequence::value_type, unsigned>::value, "foo");
// ...
如果您尚未使用 C++11,请改用BOOST_STATIC_ASSERT。
如果需要支持纯 C 样式数组,则需要做更多的工作。
另一方面,@IgorTandetnik正确地指出,您可能根本不需要明确检查。 如果您传递了一个真正无法使用的类型,编译器会给你一个(丑陋的)错误。
使用 static_assert
编写泛型函数是个好主意,因为您可以为用户提供有用的错误消息,而不是"foo"。
但是,还有另一种使用C++11
的方法:
template <typename Container, typename ValueType>
typename std::enable_if<std::is_same<Container::value_type, ValueType>::value, void>::type
next_value(Container& num, ValueType base)
{
// ...
}
如果您以前从未见过,这是一种相当神秘的方法。这使用"替换失败不是错误"(简称SFINAE
)。如果ValueType
与Container::value_type
不匹配,则此模板不会形成有效的函数定义,因此将被忽略。编译器的行为就像没有这样的函数一样。即,用户不能将函数与容器和 ValueType 的无效组合一起使用。
请注意,我确实建议使用static_assert
!如果你在那里放一个合理的错误消息,用户会感谢你一千次。
在您的情况下,我不会。
将进位更改为书籍,使用 ++ 而不是 +=,使 base 成为类型 T,n 成为auto&
。
最后,返回携带。
您的代码现在完全可以键入要求。
如果需要诊断,请静态断言操作对自定义错误消息有意义。
这让你的代码处理无符号的整数、多项式、bigint 等等。
- 如何在c++迭代器类型中包装std::chrono
- 定义模板参数的迭代器类型
- C++以迭代方式搜索混合类型地图
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 专门C++使用指针值类型的通用迭代器的模板函数?
- C++类字符串类型的迭代器
- 在迭代模板类型列表时无法停止递归
- 使用概念对具有特定值类型的任何容器进行 C++ 迭代
- 类型不可知的抽象以使用相同的运行时接口处理正向和反向迭代器和范围?
- 迭代时将指向differents类型的指针保存在std::向量中
- 如何转换不同类型的迭代器
- 如何从迭代器中找到对的类型
- C++不兼容的迭代器类型
- 如何确定迭代器在 c++ 模板函数中指向的对象的类型?
- 迭代器的模板参数:函数在调用时推断类型?
- 如何推导 std::高级迭代器类型?
- 在 stl 容器包装器中定义迭代器类型
- 对矢量<类型*>迭代器感到困惑
- C++异构类型迭代器的迭代器
- 为什么c++标准需要std::分区来满足不同类型迭代器的不同复杂性