在 C++ 中通过引用传递可选参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2816293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing optional parameter by reference in c++
提问by Moomin
I'm having a problem with optional function parameter in C++
我在 C++ 中遇到了可选函数参数的问题
What I'm trying to do is to write function with optional parameter which is passed by reference, so that I can use it in two ways (1) and (2), but on (2) I don't really care what is the value of mFoobar
.
我想要做的是编写带有通过引用传递的可选参数的函数,以便我可以通过两种方式(1)和(2)使用它,但是在(2)上我并不关心什么是的值mFoobar
。
I've tried such a code:
我试过这样的代码:
void foo(double &bar, double &foobar = NULL)
{
bar = 100;
foobar = 150;
}
int main()
{
double mBar(0),mFoobar(0);
foo(mBar,mFoobar); // (1)
cout << mBar << mFoobar;
mBar = 0;
mFoobar = 0;
foo(mBar); // (2)
cout << mBar << mFoobar;
return 0;
}
but it crashes at
但它崩溃了
void foo(double &bar, double &foobar = NULL)
with message :
带有消息:
error: default argument for 'double& foobar' has type 'int'
Is it possible to solve it without function overloading?
是否可以在没有函数重载的情况下解决它?
回答by 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.
不要对可选参数使用引用。没有引用 NULL 的概念:引用始终是特定对象的别名。
Perhaps look at boost::optional
or std::experimental::optional
. boost::optional
is even specialized for reference types!
也许看看boost::optional
或std::experimental::optional
。boost::optional
甚至专门用于引用类型!
void foo(double &bar, optional<double &> foobar = optional<double &>())
回答by In silico
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);
}
回答by kennytm
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)
回答by pkh
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);
// ...
回答by CasaDeRobison
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:
这是另一种不会导致内存泄漏的疯狂方式,您在现实生活中永远不应该使用它,但乍一看似乎符合标准,并在 Cygwin 下使用 Visual C++ 2008 & g++ 3.4.4 进行编译:
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. :)
重申:不要这样做!有更好的选择!超载可以成为你的朋友!但是,是的,如果您既愚蠢又小心,就可以做到。:)
回答by Zorayr
It is much easier to use a pointer type and setting it to NULL than setting default/optional value for a reference parameter.
使用指针类型并将其设置为 NULL 比为引用参数设置默认/可选值要容易得多。
回答by wdavilaneto
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...
Edit2:拼写和修复...
回答by Bobby_Zero
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);
我的原始函数没有返回错误字符串: 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()));
我想在错误字符串中添加验证结果,所以我实现了: 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.
这样,您就可以在validateXML 中引用errorString,而无需检查它是否有效,也不会出现内存泄漏。
回答by faya
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! :))
PS - 我知道它不愉快,但它的方式。另外一定不要留下内存泄漏!:))