c++ - 可选参数 const 引用重新分配

标签 c++ c++11

我知道这是不可能的,因为我破坏了 const 契约(Contract)的核心,我不允许以任何方式修改对象,但我还能如何选择传递参数作为引用?

假设我有一个错误代码结构和一些成员函数,我有选择地想要检查错误代码

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 如何使用 boost::system::error_code 执行此操作,但我在那里找不到任何静态对象,那么 boost 如何执行此操作?什么是干净的方法?

最佳答案

你可以手写重载:

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,所以 boost 经常使用这种重载约定,错误代码通过引用传递 vs 不传递,意思是:如果你不传递错误代码,然后抛出指示错误。您使用相同的约定来表示(afaics)忽略错误,这可能有点冒险(我认为)。

关于c++ - 可选参数 const 引用重新分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49264030/

相关文章:

c++ - 关于 CPP 文件和 header

c++ - C++中栈和堆的地址

c++ - 如何处理抽象对象的返回

c++ - C++ 中指向对象和后代的指针

c++ - 在 C++ 中给定迭代器调整 vector 大小

c++ - 存储可变模板参数并在另一个类中使用它们

c++ - Variadic 模板方法和 std::function - 编译错误

c++ - NTL 字符串到 ZZ 转换以及 ZZ 到字符串

c++ - C++17 中的 std::map::insert 更改

c++ - is_member_function_pointer 实现