【问题标题】:Can a const variable be assigned in parameters with a default value (as an optional parameter)?可以在具有默认值(作为可选参数)的参数中分配 const 变量吗?
【发布时间】:2018-07-20 14:22:20
【问题描述】:

我需要在程序中大多数函数调用的末尾添加可选参数。现在函数的参数看起来像

foo(int a, char b, const unique_ptr c)

我添加的是最后一个参数的默认值,使其看起来像

foo(int a, char b, const unique_ptr c = NULL)

可以像我所做的那样在参数中分配 const 变量吗?还是这违背了常量变量的本质?

【问题讨论】:

  • 你的编译器告诉你什么?
  • 参数const 不是函数签名的一部分。
  • unique_ptr 需要模板参数列表和正确的初始化,const 在这里无关紧要,它也是初始化而不是对默认函数参数执行的赋值(不要让存在 @ 987654326@迷惑你)
  • @GabrielKay 这是两种不同的类型。您不能将 std::unique_ptr 隐式转换为指针。
  • 使用 unique_ptr 作为参数意味着您将传递参数的唯一所有权转移给 foo 函数。是否有意传递所有权?

标签: c++ pointers constants


【解决方案1】:

限定为const 的变量可以被初始化,但之后不能更改(例如分配给)。对于任何普通变量以及函数参数都是如此。让我们将您的示例简化为

void foo(const int a = 1) {}

这本身就是一个有效的函数签名,它告诉编译器参数a在函数体内没有被修改。这将因此无法编译:

void illegalFoo(const int a = 1) { a = 2; /* Error, won't compile */ }

如果调用代码将值传递给函数

foo(3);

在这个例子中,函数参数a被初始化为3,但同样在函数体中没有改变。 std::unique_ptr 参数也是如此:

void foo(const std::unique_ptr<SomeClass> ptr = nullptr)
{
    /* No way to alter ptr here */
}

但是请注意,这个函数签名没有什么意义。通过值传递std::unique_ptr 意味着转移所有权,但是一个 const 限定的实例不能被强制转换为一个右值引用,以便从中移动构造另一个拥有的智能指针。如果没有所有权语义与此类函数相关联,则传递一个原始指针 - 它同样可以声明为 const 并默认为 nullptr

【讨论】:

  • const 变量根本无法赋值,这是初始化。
【解决方案2】:

您要做的是重载您的函数,而不是在其原始定义中为参数添加默认值。重载函数如下所示:

void foo(int a, int b) {
    // this is the original definition, takes 2 parameters, so we initialize c to 0:
    const int c = 0;
    return a + b;
}
// then, right underneath, you add an overloaded definition for the function:
void foo(int a, int b, const int c) {
    // this is the overloaded definition, takes 3 parameters
    return a + b + c;
}

这样,当你调用foo()时,参数c是完全可选的。

【讨论】:

    【解决方案3】:

    你所做的并没有错。

    请记住以下语法:

    foo(int a, char b, const unique_ptr c = NULL);
    

    基本上只是语法糖:

    foo(int a, char b, const unique_ptr c);
    foo(int a, char b) {
        foo(a, b, NULL);
    }
    

    这显然是有效且合法的,附带条件是,虽然在技术上允许将 nullptrNULL 分配给 std::unique_ptr,但这可能是一种不好的做法,因为否则不允许分配原始指针直接指向智能指针(即std::unique_ptr&lt;int&gt; ptr = new int(5); 不会编译)。

    这样写可能会更好:

    foo(int a, char b, const unique_ptr c = {});
    

    【讨论】:

      猜你喜欢
      • 2011-01-11
      • 2017-09-09
      • 2019-09-12
      • 1970-01-01
      • 2013-04-25
      • 2021-09-24
      • 2023-03-19
      • 2011-02-17
      相关资源
      最近更新 更多