可以在具有默认值(作为可选参数)的参数中分配 const 变量吗?

Posted

技术标签:

【中文标题】可以在具有默认值(作为可选参数)的参数中分配 const 变量吗?【英文标题】:Can a const variable be assigned in parameters with a default value (as an optional parameter)? 【发布时间】: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 函数。是否有意传递所有权? 【参考方案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 = );

【讨论】:

以上是关于可以在具有默认值(作为可选参数)的参数中分配 const 变量吗?的主要内容,如果未能解决你的问题,请参考以下文章

scala:作为其他参数的函数的可选默认参数

JavaScript中的可选参数[重复]

compojure-api 的可选查询参数(具有默认值)

可选输出光标作为参数

为具有更多限制性默认值的可选参数强制使用更广泛的类型

将空数组作为可选参数的默认值传递[重复]