我只是尝试将自己的函数实现为int
转换的字符串。
我的功能如下:
int func(string s)
{
if error return -1;
else do something and return the value
}
我只有一个疑问,如果我的字符串是s =" -1",那么我如何区分" -1"为错误和字符串的正确转换返回。谢谢你的帮助。我希望我的问题很清楚。
答案 0 :(得分:3)
您有多种选择可以进行不同的权衡。
<强> 1。例外即可。在错误情况下抛出异常。不需要直接在调用站点捕获异常,但可以在调用层次结构中进一步处理异常,其中您有更多上下文来处理错误。我甚至会说,如果你总是在try-catch块中包装你的函数调用,你可能会误解异常的优势。
int func(const std::string& s);
<强> 2。可选的返回值。 std::optional
,可在C ++ 17中使用(或在boost::optional
或技术规范(TS)之前使用)。这是明确声明不返回值是在调用函数时必须考虑的有效情况。
std::optional<int> func(const std::string& s);
很酷的是显式的操作符bool允许这个习语:
if (std::optional<int> i = func("hello")) // or even auto
use(*i);
第3。指针返回值。使用类似于前一点的语义,当返回存储的元素时,例如,这可能是需要的。在搜索中。如果未找到,则返回nullptr
。与std::optional
相反,它的缺点是它需要内存/生命周期管理(要么保证对象超过调用,要么动态分配)。如果确实需要使用std::unique_ptr
动态分配,请不要返回必须由调用者显式删除的指针。请记住,动态分配是昂贵的,并且对int
等小对象几乎总是过度杀伤。此外,您需要考虑const正确性。
int* func(const std::string& s);
const int* func(const std::string& s);
std::unique_ptr<int> func(std::string& s);
<强> 4。检查和输出参数习惯用法。有一个带输出参数的函数。如果它生成一个值,它会将结果写入该参数并返回true,否则返回false。
bool func(int& out);
这允许调用如下。缺点是您不能直接初始化对象(因此不能使用const
- 限定,默认构造或不可分配的对象,例如)。
int value;
if (func(value))
use(value);
<强> 5。断言即可。这是许多人忽略的事情,特别是那些来自Java等语言的人,大多数错误都是以异常方式明确处理的。如果唯一一个返回无效值的情况是函数的错误调用 - 即程序中的逻辑错误(不是说bug) - 那么通常更可取的是尽快识别它。调试器将在失败的断言时立即停止,而您的高效代码随之完全优化。
int func(const std::string& s);
断言非常适合检查函数的前置或后置条件。它们对于发出在运行时无法有意义处理的错误信号特别有用。如果它们失败,则意味着您的程序逻辑被破坏,并且由于这不应该首先发生,因此没有好办法从情况中恢复。由于您的应用程序处于意外状态,执行更多代码可能会使事情变得更糟。
答案 1 :(得分:1)
您的功能设计可能是:
int func(string s, int *out)
{
if error return -1;
else {
do something and set *out to the value;
return 1;
}
}
正如评论所概述的那样,如果要表示有效值和错误,则-1
的返回值会重载。由于没有可以表示两者的整数值,因此需要额外的返回值。在此设计中,函数的返回值表示成功或失败,*out
参数返回结果。你可以交换这两个(参数接收成功或失败,返回值是值)。
答案 2 :(得分:1)
你可以抛出异常。
int func (string const & input)
{
if (error)
throw std::runtime_error("stuff happenend")
else
return value;
}
答案 3 :(得分:0)
我会使用boost::lexical_cast
并让来电者处理bad cast exceptions
。
// will throw bad_lexical_cast if any issue.
int convert(const std::string& num) {
return boost::lexical_cast<int>(num);
}
int main()
{
try {
std::cout << convert("1") << "\n";
std::cout << convert("-1") << "\n";
std::cout << convert("abc") << "\n";
} catch (const boost::bad_lexical_cast& blc) {
std::cout << blc.what() << "\n";
}
return 0;
}
这很简单且经过充分测试。
更简单的方法是使用boost::lexical_cast<T>()
而不使用convert
函数,它只为您提供包装器;
试试here