【问题标题】:C++ Optional std::vector argument for function函数的 C++ 可选 std::vector 参数
【发布时间】:2016-09-08 12:39:34
【问题描述】:

我在这里看到了一些答案,但它们可能不适用于这里。我有一个(成员)函数,主要与一个参数(第一个)一起使用:

const std::complex<double> Class::func(const std::complex<double> &x, \
                                       std::vector<double> &y = 0, \
                                       std::vector<double> &z = 0) const;

我希望yz 是可选的,甚至可能基于string 类型的第四个参数,例如:func( , , , const std::string &amp;choice),但这样我只能将一个参数传递给功能和其他两个不使用。例如,如果我确实传递了y,它的声明必须在调用func() 之前完成,z 也是如此,但我希望这是可选的,该函数可能有点重数学方面,如果不需要它们,则无需增加计算两个额外向量的负担。这可能吗?

【问题讨论】:

  • 好吧,如果你可以等待你的编译器已经有了它,那就是std::optional。否则有boost::optional
  • 传递一个指针而不是一个引用,并将它们的默认值设置为 nullptr。然后检查你的代码中是否有 y!=nullptr 和 z!=nullptr,你就完成了。一个小警告,除非你有它们的默认值,否则你将无法在这些参数之后有参数(所以你的字符串应该有一个默认值,尽管你可以使用更小的类型来减轻它的重量)。
  • 你需要从函数内部修改 y 或 z 吗?换句话说,y 和 z 可以是 const std::vector&lt;double&gt; &amp;z 类型
  • @log0 是的,当它们被使用时。我需要先定义std::vector z; z.resize(x);,然后用它来填充数据,这直接依赖于x参数。

标签: c++ vector default-arguments


【解决方案1】:

使用指针并传递nullptr,检查这个..

const std::complex<double> Class::func(const std::complex<double> &x, \
                                       std::vector<double> *y = nullptr, \
                                       std::vector<double> *z = nullptr) const;

我在这里默认了它们,但这是可选的......

【讨论】:

  • 这需要某种内存管理吗?如delete[] 或类似?
  • 除非还有new,否则delete 什么都没有。你只能delete 那些你newed 的东西。
  • 如果你调用这个函数 fith func(vec1,&amp;vec2,&amp;vec3) 而 vec2 和 vec3 不是局部变量。仅当您使用 new 分配它们时
  • @Nim 你的版本看起来是最简单和最有前途的。我现在正在尝试。如果它按预期工作,我会选择你的作为答案。感谢大家的解决方案。
【解决方案2】:

鉴于std::vector 的使用,“空”vector 是什么意思?这可以用作您需要的“可选”值。

对原代码的一些注释; “null”引用无效,即std::vector&lt;double&gt; &amp;y = 0 无法编译。可以使用指针代替它,这并不意味着需要立即分配。

const std::complex<double> Class::func(
    const std::complex<double> &x,
    std::vector<double>* y = nullptr,
    std::vector<double>* z = nullptr) const;

函数重载通常是这种情况的答案;函数的内部结构取决于每个最终实现...

const std::complex<double> Class::func(
    const std::complex<double> &x) const;
const std::complex<double> Class::func(
    const std::complex<double> &x,
    std::vector<double>& y) const;
const std::complex<double> Class::func(
    const std::complex<double> &x,
    std::vector<double>& y,
    std::vector<double>& z) const;

还有std::optional

const std::complex<double> Class::func(
    const std::complex<double> &x,
    std::optional<std::vector<double>> &y,
    std::optional<std::vector<double>> &z) const;

如果您的标准库中没有,还有boost::optional

【讨论】:

  • 是否会传递std::vector&lt;double&gt; &amp;(此处的预期用法),因为参数会导致转换为对此std::optional 的引用?我不相信。
  • 这取决于调用者以及他们如何创建vector。如果它就地创建(在optional 中),则保持类似的语义。如果他们在可选之外创建它,那么是的,副本被创建。
  • 这还能用吗?您正在将非常量引用传递给临时。也许是 optional reference 而不是 reference to optional
  • @Revolver_Ocelot。好点子。 optional&lt;T&amp;&gt; 不能为 std 编译,IIRC,但是 boost 很好。
【解决方案3】:

引用不能是可选的,但有一个叫做boost::optional&lt;&gt;的东西

如果您担心复制操作,您应该改用指针并使用 nullptr 作为默认值。

如果你还想让它依赖于最后的字符串,你可以编写一个包装函数

只需添加另一个功能:

const std::complex<double> Class::func(
    const std::complex<double> &x,
    std::string str,
    std::vector<double> *y = nullptr,
    std::vector<double> *z = nullptr) const
{
    if(str == ...)
        return func(....);
    else
       return func(....); //different call
}

【讨论】:

  • 您也可以默认使用 emtpy 向量 ... y = {} ... 仅适用于 const&amp; 并且 OP 需要修改可选向量。
  • 啊没看到。我删除了部分。
猜你喜欢
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多