Passing optional parameter by reference in c++

时光怂恿深爱的人放手 提交于 2019-11-27 19:20:20

The default argument of a (mutable) reference must be an l-value. The best I can think of, without overloading, is

static double _dummy_foobar;
void foo(double &bar, double &foobar = _dummy_foobar)
Potatoswatter

Don't use references for optional parameters. There is no concept of reference NULL: a reference is always an alias to a particular object.

Perhaps look at boost::optional or std::experimental::optional. boost::optional is even specialized for reference types!

void foo(double &bar, optional<double &> foobar = optional<double &>())

Why can't you use function overloading? Surely it's the easiest solution to your problem?

void foo(double &bar, double &foobar) 
{ 
   bar = 100; 
   foobar = 150; 
}

void foo(double &bar) 
{ 
   double foobar = 0.0;
   foo(bar, foobar);
}

Another way to do this is to use pointers instead of references. This provides the semantics that you want without overloading. (Personally, I'd probably go with overloading.)

void foo(double* bar, double* foobar = 0)
{
   if (bar) *bar = 100;
   if (foobar) *foobar = 150;
}

   // ...

   foo(&mBar, &mFoobar);

   // ...

   foo(&mBar);

   // ...

Here is another crazy way that does not result in memory leaks, which you should never use in real life, but seems to be standard compliant at first glance and compiles with Visual C++ 2008 & g++ 3.4.4 under Cygwin:

void foo(double &bar, double &foobar = (*((double*)0)))
{
   bar = 100;
   double* pfoobar = &foobar;
   if (pfoobar != 0)
       foobar = 150;
}

To reiterate: DON'T DO THIS! THERE ARE BETTER OPTIONS! OVERLOADING CAN BE YOUR FRIEND! But yeah, you can do it if you're foolish and careful. :)

It is much easier to use a pointer type and setting it to NULL than setting default/optional value for a reference parameter.

Speaking in terms of Object Oriented paradigm: If given class has and "Default", this Default must declared accordingly, and then may be used as an "Default Parameter" Ex:

class Pagination {
private:
    int currentPage;
public:

    //...
    Pagination() {
        currentPage = 1;
        //...
    }

    // your Default Pagination (Must be initialized before thread concurrency)
    static Pagination& Default() {
        static Pagination p; 
        return p;
    }
};

On your Method ...

     //...
     std::vector<User>
     findByFilter(User& audit, Pagination& p = Pagination::Default() ) {
     // ...

Edited: This solution is quite suitable since in this case it is an "global default" Pagination and a single "reference" value. You will also have the power to change default values such as navigation/display preferences and etc.

Edit2: spelling and fixing...

This is how I solved this question:

My original function didn't have a returned error string: bool MyClass::validateXML(const QString& fileName, const QUri& schemaUri);

I wanted to add the results of the validation in an error string so I implemented: bool MyClass::validateXML(const QString& fileName, const QUri& schemaUri, QString& errorString = *(std::make_unique().get()));

This way, you can reference the errorString in validateXML without checking if it's valid, and no memory leaks.

You can do this crazy way:

void foo(double &bar, double &foobar = (*(new double())))

P.S. - I know its not pleasant but its the way. Also be sure not to leave memory leaks! :))

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!