【问题标题】:What effect does a const have for effect before the return type in a function? [duplicate]const 在函数中返回类型之前对效果有什么影响? [复制]
【发布时间】:2016-10-06 10:49:24
【问题描述】:

我有以下代码:

const string getConstString()
{
    return "MyConstString";
}

int main()
{
    string str1 = getConstString();
    cout << str1 << endl;
}

const关键字在这里有什么作用?

【问题讨论】:

  • 重新复制,James Kanze 那里接受的答案不正确。
  • 是的,是的,为函数定义添加前缀意味着返回的对象将是 const。这意味着,如果你想存储它,你必须将它存储在一个 const 对象中。
  • void main 在 C 和 C++ 中始终无效。请不要使用void main 发布代码,因为它会误导初学者,并且通过直接复制和粘贴来测试您的代码更加困难。 FTFY。
  • 抱歉,正如我所写,詹姆斯的回答不正确。它只是旧的,因此不完整。
  • 双重抱歉。 C++11 §3.10/4 “类纯右值可以有 cv 限定类型;非类纯右值总是有 cv 非限定类型”意味着 James 声称“忽略非类类型的返回类型的顶级 cv 限定符“ 是不正确的。我投了反对票并添加了解释。我已经在这里更新了我的答案,其中包含如何忽略限定符的标准+示例。

标签: c++


【解决方案1】:

一个显着的影响是您不能从const 结果中移动

在 C++ 在 C++11 中直接支持移动语义之前,一个常见的建议是创建返回类型 const 以强制客户端代码仅以有意义的方式将结果用作值(而不是作为一个可变对象)。

在 C++11 之后的建议是相反的:不要返回值 const,因为这会阻止移动。


例子:

#include <iostream>
#include <string>
using namespace std;

auto m() -> string { return {}; }
auto c() -> const string { return {}; }

void check( string&& ) { cout << "mutable\n"; }
void check( string const&& ) { cout << "const\n"; }

auto main()
    -> int
{
    check( m() );
    check( c() );
}

这个输出

可变的 常量

... 表明函数c 的结果中的const 对调用代码来说非常明显。


使用 int 而不是 string 输出是 2 × “mutable”,显示了在处理内置类型和类类型方面的微妙而令人惊讶的差异:顶级 const 被忽略对于内置类型的结果,例如 int

C++11 §3.10/4 (basic.lval/4):

类纯右值可以有 cv 限定类型;非类纯右值始终具有 cv 非限定类型。

值得注意的是,这是 prvalue 表达式类型的规则,而不是函数声明的重写规则,例如衰减到数组的指针类型或函数类型形式参数。即,函数的类型不受影响。 const 还在类型中:

#include <iostream>
#include <type_traits>      // std::is_same
using namespace std;

#define STATIC_ASSERT( e ) static_assert( e, #e " <- is needed." )

auto c() -> const int{ return {}; }

auto main()
    -> int
{
    // Function type:
    STATIC_ASSERT(( is_same<decltype( c ), auto()->const int>::value ));
    STATIC_ASSERT(( not is_same<decltype( c ), auto()->int>::value ));

    // prvalue type:
    STATIC_ASSERT(( is_same<decltype( c() ), int>::value ));
    STATIC_ASSERT(( not is_same<decltype( c() ), int const>::value ));
}

【讨论】:

  • @BeyelerStudios:不,复制省略仍然可以正常工作。
  • 你能解释一下防止移动吗?
  • @Niklas 从临时移动意味着修改该临时(以表明你偷了它的资源)。您不能修改 const 对象。因此 const 临时对象不能被移出。
  • @Cheersandhth.-Alf 如果我没记错的话,规则是如果类型是内置类型(而不是引用),则返回类型中最顶层的 const 将被忽略。对吗?
  • @bolov:我认为这是正确的。但不确定标准在哪里这么说。
猜你喜欢
  • 1970-01-01
  • 2018-11-05
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 2017-06-20
  • 2019-10-04
  • 2015-11-24
  • 1970-01-01
相关资源
最近更新 更多