我正在尝试编写一个函数来枚举一些特定的基数,其中数字存储在某种列表中。这是一个例子,采用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 vector不一定需要是一个vector,它可以是一个数组,或者实际上是为它定义了std :: begin()和std :: end()的任何类型。有没有办法表达num可以是begin()和end()的任何东西,但它的元素必须有unsigned int类型?
答案 0 :(得分:1)
如果您真的想检查一下,请尝试:
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正确地指出你可能根本不需要明确检查。如果传递一个真正无法使用的类型,编译器会给你一个(丑陋的)错误。
答案 1 :(得分:0)
使用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
不匹配,则此模板不会形成有效的函数定义,因此会被忽略。编译器的行为就好像没有这样的功能。即,用户不能将该函数与Container和ValueType的无效组合一起使用。
请注意,我建议使用static_assert
!如果你在那里放了一个合理的错误信息,用户会感谢你一千次。
答案 2 :(得分:0)
我不会在你的情况下。
将进位更改为书籍,使用++而不是+ =,将基数设为类型T,将n设为auto&
。
最后,返回进行。
您的代码现在正好符合要求。
如果您想要诊断,静态断言操作对自定义错误消息有意义。
这是让你的代码处理无符号整数,多项式,bigint,等等。