可以在具有默认值(作为可选参数)的参数中分配 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);
这显然是有效且合法的,附带条件是,虽然在技术上允许将 nullptr
或 NULL
分配给 std::unique_ptr
,但这可能是一种不好的做法,因为否则不允许分配原始指针直接指向智能指针(即std::unique_ptr<int> ptr = new int(5);
不会编译)。
这样写可能会更好:
foo(int a, char b, const unique_ptr c = );
【讨论】:
以上是关于可以在具有默认值(作为可选参数)的参数中分配 const 变量吗?的主要内容,如果未能解决你的问题,请参考以下文章