我知道这是不可能的,因为我打破了const constract的核心,我不允许以任何方式修改对象,但我怎么可选择传递参数作为参考?
假设我有一个错误代码结构和一些成员函数我可选择检查
的错误代码struct my_error_code {
int val;
std::string message;
};
struct my_complicated_obj {
/* Compiles fine, understandbly, ec is not optional*/
void do_stuff(/*params,*/my_error_code& ec){
ec = {0x10, "Something went wrong"};
return;
}
void do_stuff_optionally(/*params,*/ const my_error_code& ec= {}){
/* There is no overload of assignment or constructos I can trick into allowing this.. */
ec = {0x20, "Something is wrong."};
return;
}
};
在上面do_stuff_optionally
显然不会编译。我当时知道的解决方案就是
my_error_code& my_error_code_default(){
static my_error_code ec = {0, "No Error"};
return ec;
}
void do_stuff_optionally_not_so_very_clean(/*params,*/ my_error_code& ec = my_error_code_default()){
ec = {0x11, "Something went wrong."};
}
但是顾名思义这不是很干净,保留一个全局对象(本质上)只是为了让我可以通过引用将我的类型用作可选的可变参数。
我试着用boost::system::error_code
查看boost是如何做到的,我找不到任何静态对象,那么boost如何做到这一点?什么是干净的方法?
答案 0 :(得分:1)
你可以手写出过载:
void do_stuff_optionally(/*params,*/ my_error_code& ec);
void do_stuff_optionally(/*params */) {
my_error_code ec;
do_stuff_optionally(/*params,*/ ec);
}
那就是说,如果你的函数没有返回任何东西,你可以直接返回更清晰的错误代码。如果它返回其他内容,您可以使用boost::variant
返回对象或错误代码。
最后,你应该知道,因为你正在使用boost,所以这种提升经常使用这种重载约定,错误代码通过引用而不是传入,意思是:如果你没有传入错误代码,那么抛出表示错误。您使用相同的约定来表示(afaics)忽略错误,这可能有点冒险(我认为)。
答案 1 :(得分:1)
摆脱const
,并使用指针而不是引用:
struct my_complicated_obj {
void do_stuff(/*params,*/my_error_code& ec){
do_stuff_optionally(/*params,*/ &ec);
}
void do_stuff_optionally(/*params,*/ my_error_code *ec = nullptr){
if (ec)
*ec = {0x20, "Something is wrong."};
}
};
让调用者决定是否需要错误代码。