我需要在程序中大多数函数调用的末尾添加可选参数。现在,函数的参数沿
foo(int a, char b, const unique_ptr c)
我添加的是最后一个参数的默认值,使其成为可选参数,因此它看起来像
foo(int a, char b, const unique_ptr c = NULL)
可以像我一样在参数中分配const变量吗?还是这违背了常量变量的本质?
答案 0 :(得分:4)
合格为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
。
答案 1 :(得分:0)
您要执行的操作是重载,而不是在其原始定义内为参数添加默认值。重载函数如下所示:
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;
}
这样,当您调用c
时,参数foo()
完全是可选的。
答案 2 :(得分:0)
您所做的没有错。
请记住以下语法:
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 = {});