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

时间:2018-07-20 14:22:21

标签: c++ pointers const

我需要在程序中大多数函数调用的末尾添加可选参数。现在,函数的参数沿

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

我添加的是最后一个参数的默认值,使其成为可选参数,因此它看起来像

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

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

3 个答案:

答案 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);
}

这显然是有效和合法的,附带条件是,虽然从技术上允许将nullptrNULL分配给std::unique_ptr,但这可能是一个坏习惯,因为您不是否则可以将原始指针直接分配给智能指针(即std::unique_ptr<int> ptr = new int(5);将不会编译)。

最好这样写:

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