我有一个函数声明为:C++如何检查一个函数是否正在接收一个unsigned int?
void foo(unsigned int x)
我如何检查了foo()不接受负数? 我想,如果我调用foo(-1)抛出一个异常, 当然,因为x被自动转换为无符号,我无法检查其积极性,如:
if not(x>=0){ do_something();};
或类似检查。
我有一个函数声明为:C++如何检查一个函数是否正在接收一个unsigned int?
void foo(unsigned int x)
我如何检查了foo()不接受负数? 我想,如果我调用foo(-1)抛出一个异常, 当然,因为x被自动转换为无符号,我无法检查其积极性,如:
if not(x>=0){ do_something();};
或类似检查。
是不是真的做任何好办法,但你可以用一些技巧,做到这一点:
1)声明一个未定义的更好的匹配:
void foo(unsigned int x) {
//do something
}
void foo(int x);
2)使用的typeid确定类型。
我喜欢#2的要点,并且使用C++ 11更好公用事业。我确定[this](http://liveworkspace.org/code/5d72d4ed342ba48c82076217f51efffe)并不完美,但它确实给出了可能性的要点。 – chris
@chris我也喜欢。另外,还有'std :: is_unsigned',它可以用来保持特定类型的整数(short和long等)的灵活性。 – jogojapan
至于你能扩展点2吗? @jogojapan所以在标准库中有这样的功能? – lucacerone
您定义了该函数,因此需要参数unsigned int
,因此它不可能接收到负值。
如果用int
参数调用它,该值将从int
隐含转换为unsigned int
,并且该转换的结果已定义良好。这是该语言的一个特性,除非编译器碰巧给你提供了一种方法,否则你不能关闭它 - 而且我不知道这样做的编译器。
至于你的功能而言,这两个调用:
foo(-1); /* -1 is converted to unsigned int, to the value UINT_MAX */
foo(UINT_MAX);
是无法区分的。这不是唯一的情况; 任何负数int
值将被转换为有效的unsigned
值。
如果非常大的值被认为对foo()
无效,那么您可以检查参数值是否在某个“合理”范围内 - 但是定义什么是“合理”并不总是那么容易。
我不认为这解决了这个问题,问题不在于foo是否可以处理'INT_MAX'和'UINT_MAX'之间的数字,问题是如何在传递类型为int的参数而不是unsigned int时获得编译器错误。 – wich
我不是一个C++专家,但是...
你只需要固定数量的比特(通常为32或64)来表示的整数。如果你知道你永远不会有一个小于零的整数,你可以使用所有这些位并存储一个更大的数字。如果您的编号可能小于零,则编译器必须为该符号预留一点位。
它比这更复杂 - 请参阅Wikipedia article on 2's complement。长话短说,在foo内部,如果你看到x是“真的很大”,那么你可能已经通过了一个负数。
检查您的编译器文档是否为int vs uint的大小。
您可能会想要将参数更改为普通整数void foo(int x)
,或者只是放松一下,知道您当前的设置x不会小于零。
正如其答案所示,您可以添加foo
的重载版本,该版本需要int
参数。既然你说你想foo(-1)
抛出异常,你可以有超载foo()
做到这一点:
#include <iostream>
class Wrong_Type {
public:
Wrong_Type(){}
};
void foo(unsigned n) {
std::cout << "In foo, unsigned n = " << n << "\n";
}
void foo(int n) {
std::cout << "In foo, int n = " << n << "\n";
throw Wrong_Type();
}
int main() {
try {
foo(-1);
}
catch (Wrong_Type) {
std::cout << "Caught Wrong_Type exception\n";
}
}
当我运行此,输出是:
In foo, int n = -1
Caught Wrong_Type exception
但是,这不是一个理想的解决方案,因为它会抛出基于参数类型的异常,而不是其值。 1
和-1
都是int
类型,所以调用foo(1)
也会引发异常。而一些其他有效的呼叫,例如foo(1.0)
,则变得模糊不清。
如果您可以用foo(1U)
替换foo(1)
,其中1U
是unsigned int
类型的常量,那么这可以工作。
为什么不直接让它变成'int'? – nneonneo
如果'foo'通过一个隐式转换的'int',比较以确保x <= std :: numeric_limits :: max()' – oldrinb
但是如果我传递的正是最大数? – lucacerone