c++ - 返回对内部对象的引用时的常量性

标签 c++ c++11 language-lawyer

<分区>

我试图理解以下情况,它的行为与我的预期不同。

给定以下代码示例:

class ConstTestClass
{
    std::deque<unsigned long long> deque;
public:
    const std::deque<unsigned long long int> &getDeque() const{return deque;}
};

int main()
{
    ConstTestClass constTestClass;
    auto constDeque = constTestClass.getDeque();
    constDeque.emplace_back(1ULL);
}

我希望调用 constDeque.emplace_back(1ULL);失败,因为我期待 constDeque作为对 const std::deque<> 的引用, 但它实际上在 GCC 5.4.0 上编译没有任何错误。

如果我将上面的行更改为 const auto constDeque = constTestClass.getDeque();它无法按预期编译,因为 constDeque now 是预期的类型。

我试图理解为什么 auto可以从返回类型中删除 const-ness 以及我理解的错误所在。

编辑: 这不是重复回答。我仍在寻找一种方法来确保调用者始终获得对内部对象的 const 引用(或指针),因此调用者将看到内部对象的状态更改而无法修改它。

最佳答案

auto使用与 template argument deduction 相同的规则.为了进一步阐明它,假设您有一个函数(例如 foo ):

template<typename T>
void foo(T v) {
  v.emplace_back(1ULL);
}

然后您执行以下操作:

std::deque<unsigned long long> dq;
const std::deque<unsigned long long> &dqr = dq;
foo(dqr);

这段代码也会通过编译器 Live Demo .发生这种情况是因为根据模板参数推导规则 T将被推断为 std::deque<unsigned long long>dqr将通过拷贝传递给foo .

现在想象一下 auto是模板参数(例如 T ):

T constDeque = constTestClass.getDeque();

因为 auto使用与模板参数推导相同的规则,如 foo 中的示例所发生的那样,它会推导出Tstd::deque<unsigned long long> .

因此,您正在创建 const 的拷贝成员(member)std::deque成员变量。为了获得您预期的行为,您必须为您的 auto 提供一点帮助演绎并写出:

auto &constDeque = constTestClass.getDeque();

或者,如果您想进一步向您代码的读者说明生成的 auto扣除是const您可以显式添加限定变量 const限定符为:

auto const &constDeque = constTestClass.getDeque();

关于c++ - 返回对内部对象的引用时的常量性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38457754/

相关文章:

c++ - 在 C++ 中读取 excel 表的单元格

c# - "mono_add_internal_call"是否可以仅使用 CLR 托管?

c++ - 为什么不能在全特化中引入新的模板参数?

java - 在 CNI/C++ 代码中实例化模板类

c++ - 如何调用仅给出其名称的方法?

c++11 - 如何定义此提升精神规则的AST?

c++ - 用户定义的数字文字可以紧跟一个点吗?

c++ - 仅移动类型的 back_inserter

c++ - 是 *this = Ctor();清除对象状态合法有效?

c++ - #error 指令中是否允许使用非拉丁字符?