Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 可选参数常量引用重新分配_C++_C++11 - Fatal编程技术网

C++ 可选参数常量引用重新分配

C++ 可选参数常量引用重新分配,c++,c++11,C++,C++11,我知道这是不可能的,因为我正在破坏const constract的核心,我不允许以任何方式修改对象,但我如何选择传递参数作为引用 假设我有一个错误代码结构和一些成员函数,我可以选择检查它的错误代码 struct my_error_code { int val; std::string message; }; struct my_complicated_obj { /* Compiles fine, understandbly, ec is not optional*/

我知道这是不可能的,因为我正在破坏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\u(可选)
中,显然不会编译。我当时知道的解决办法是

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\u code
研究boost是如何做到这一点的,但我在那里找不到任何静态对象,那么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通常使用这种重载约定,错误代码通过引用传递,而不是通过not传递,意思是:如果您没有传递错误代码,那么抛出以指示错误。您正在使用相同的约定来表示(afaics)忽略错误,这可能有点危险(我认为)。

摆脱
常量,使用指针而不是引用:

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."};
    }
};

让调用者决定是否需要错误代码。

I如果您使用的是C++11,则有
boost::optional
。您也可以通过指针传递并默认为
nullptr
。只需使用一些包装器。编写
optional
在内部存储指针非常简单。除了作为通用包装器外,您不能轻松重载
运算符。
,因此它最终看起来就像一个指针。无论如何,为什么您可能要忽略一个错误?扩展库,现在没有错误代码,我不想让它变得简单,而不是破坏接口。不是我,我也很感激你的回答,但是重载不是一个选项,返回类型可能不是空的。@arynaq呃,为什么重载不是一个选项?你必须提供更多的细节。如果返回类型不是void,我的答案不会受到任何重大影响;您只需执行
返回do\u stuff\u optionall(/*parms,*/,ec)