C++ 在c+中通过引用传递可选参数+;

C++ 在c+中通过引用传递可选参数+;,c++,pass-by-reference,optional-parameters,C++,Pass By Reference,Optional Parameters,我对C中的可选函数参数有问题++ 我想做的是用可选参数编写函数,该参数通过引用传递,这样我可以用两种方式使用它(1)和(2),但在(2)上,我并不真正关心mFoobar的值是多少 我尝试过这样的代码: void foo(double &bar, double &foobar = NULL) { bar = 100; foobar = 150; } int main() { double mBar(0),mFoobar(0); foo(mBar,mFooba

我对C中的可选函数参数有问题++

我想做的是用可选参数编写函数,该参数通过引用传递,这样我可以用两种方式使用它(1)和(2),但在(2)上,我并不真正关心
mFoobar
的值是多少

我尝试过这样的代码:

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;
}
留言:

error: default argument for 'double& foobar' has type 'int'
是否可以在不重载函数的情况下解决此问题?

引用(可变)的默认参数必须是l值。在没有过载的情况下,我能想到的最好的方法是

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

为什么不能使用函数重载?这肯定是解决你问题的最简单方法吗

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

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

不要对可选参数使用引用。没有引用NULL的概念:引用始终是特定对象的别名

也许看看或者
boost::optional
甚至专门用于参考类型

void foo(double &bar, optional<double &> foobar = optional<double &>())
void foo(双重&bar,可选foobar=optional())

你可以用这种疯狂的方式:

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

附言-我知道这并不令人愉快,但这是一种方式。还要确保不要留下内存泄漏!:))

另一种方法是使用指针而不是引用。这在不重载的情况下提供了所需的语义。(就我个人而言,我可能会选择重载。)


这是另一种不会导致内存泄漏的疯狂方式,在实际生活中,它不应该使用,但乍看起来似乎是标准兼容的,在CygWin下面用Visual C++ 2008和G++4.4.4编译:

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

重申:不要这样做!有更好的选择!超载可以是你的朋友!但是,是的,如果你既愚蠢又小心,你可以做到

使用指针类型并将其设置为NULL要比为引用参数设置默认值/可选值容易得多

从面向对象范例的角度来说:如果给定的类具有和“Default”,则必须相应地声明该默认值,然后可以将其用作“Default参数” 例:

根据你的方法

     //...
     std::vector<User>
     findByFilter(User& audit, Pagination& p = Pagination::Default() ) {
     // ...
/。。。
向量
findByFilter(用户和审核,分页&p=Pagination::Default()){
// ...
编辑:此解决方案非常适合,因为在这种情况下,它是一个“全局默认”分页和一个“参考”值。您还可以更改默认值,如导航/显示首选项等


编辑2:拼写和修复…

我就是这样解决这个问题的:

我的原始函数没有返回的错误字符串: boolmyclass::validateXML(常量QString和fileName,常量QUri和schemaUri)

我想将验证结果添加到错误字符串中,因此实现了: bool MyClass::validateXML(常量QString和文件名, 康斯特库里和西马里, QString&errorString=*(std::make_unique().get())

这样,您就可以在validateXML中引用errorString,而无需检查它是否有效,也无需检查内存泄漏。

void foo(双栏&bar,
double&foobar=const_cast(静态_cast(0.0)))
{
巴=100;
foobar=150;
}

当然不是-即使您可以传递空引用,当您尝试为函数赋值时,您认为函数内部会发生什么?编译错误不是崩溃。您的代码不是“崩溃”,这是一个编译错误。只有在您完全构建程序并尝试运行它之后,才会发生崩溃。在这种情况下,任何人的可能副本都应该真正吞下他们的自豪感和审美偏好-并使用
*const
指针。它是一个间接的,就像一个引用一样-但具有可空性/可测试性。为什么要用虚拟变量、Boost的膨胀等使事情复杂化?当语言提供的核心特性与我所能说的完全相符时?为提问者定义左值可能是值得的。(本质上,非正式地说,“可以指定的东西”)@pkh该定义很常见,但却是错误的。一些右值也可以分配给,例如
std::string(“hello”)=world
,而一些左值不能分配给,例如没有赋值运算符的C数组和对象。(当然,也不能分配给const左值,但这似乎很容易理解。)如果读取虚拟对象,这可能会带来微妙的线程安全问题。为了进一步安全,请在
内部
命名空间中定义
\u dummy\u foobar
,并在函数
foo
中使用
foo
if
&foobar!=&internal::\u dummy\u foobar
\u dummy\u foobar
执行可选操作当然,它回答问题的可能性是有限的,但我怀疑问题背后的动机……为什么当C++提供了一个可替代的间接可忽略的/可检查的变量时,为什么会麻烦地分配一个无用的虚拟变量?它被称为指针!我可以,但我只是想知道它是否是PO。在不超载的情况下解决问题是可能的。想象一下,在一个人们非常讨厌超载的小岛上醒来:)@Moomin我猜“我讨厌默认参数”island有更多的居民;-)重载函数应该是类中保留的伪布尔的更好选择,特别是当有其他类继承自基类时。@silico中,如果
foo
有更多的代码行,可选的ref变量
foobar
在第一个重载
void foo(双栏和双栏)
?那么这个想法肯定是一种代码复制,对吗?即使它不会导致未定义的行为,在实际使用的情况下,安全删除可选参数的可能机制是什么?将其设置为智能ptr,然后就可以了!无法避免泄漏-您无法在函数内部判断内存是否是通过默认参数分配的,并且在函数之外没有办法kno
void foo(double &bar, double &foobar = (*((double*)0)))
{
   bar = 100;
   double* pfoobar = &foobar;
   if (pfoobar != 0)
       foobar = 150;
}
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;
    }
};
     //...
     std::vector<User>
     findByFilter(User& audit, Pagination& p = Pagination::Default() ) {
     // ...