const成员函数中模板成员的常量

时间:2016-01-25 14:42:22

标签: c++ function templates const member

如何将const应用于class TcpSocket; class TcpThread { TcpSocket* Listener() const; std::vector< TcpSocket* > sockets_; }; TcpSocket* TcpThread::Listener() const { auto s = sockets_.front(); return s; } 成员函数中的模板成员?我发现以下内容很有趣(这是在VS15中):

auto

我添加了TcpSocket*来澄清发生了什么。它推导为front,因此正在选择sockets_.erase(sockets_.begin()); 的非常量版本。但是,如果我插入

sockets_

作为第一行代码,无法编译,基本上说constconst

它的工作原理是有道理的,但这里显然有更多的事情,而不仅仅是在一个const成员函数中将每个成员视为#!/usr/bin/env perl use strict; use warnings; my %mac_lookup; while ( <> ) { my @fields = split; if ( $fields[0] =~ m/^\d{2}:/ ) { $mac_lookup{$fields[1]} = $fields[0] } else { my ( $key ) = $fields[3] =~ m,([\w\-]+)/,; print join "\t", @fields[0,1], $mac_lookup{$key},"\n"; } }

4 个答案:

答案 0 :(得分:3)

sockets_内的

Listenerconst。让我们来看看front返回的内容:

reference front();
const_reference front() const;

因此,我们会获得const_reference,在这种情况下为TcpSocket * const&

这是您的期望不正确的地方。为了清晰起见,删除参考文献,您需要const TcpSocket*,它会为您提供TcpSocket * const。前者是指向const TcpSocket的指针,后者是指向const的{​​{1}}指针。

所以TcpSocket给你的是一个指针,你不能改变为你可以改变的front

因此,使用其指针可用于修改此指针的非常量副本是完全有效的:

TcpSocket

答案 1 :(得分:2)

这不是调用front的非const版本,只是你存储指针,然后你将它放入auto,它总是推导出值(和不是参考 - 你需要auto& =)。因为您正在复制const指针,所以您拥有自己的副本,因此省略const,除非您以这种方式明确定义它。这就是为什么你要推断TcpSocket*而不是TcpSocket* const

如果您想验证这一点,请尝试执行auto& s = _sockets.front()并查看然后的类型。

请注意。也是因为你存储了一个指针,你得到的vector::const_reference指向 const指针,而不是指向const 的指针。

容器本身,在该范围内是const,意味着您无法更改其元素序列或它们指向的内容。所以你不能说_sockets.erase()也不能说_sockets[0]然而,因为元素本身是指向非const TcpSocket的指针,这意味着你可以用它们做任何你想做的事情。这是你无法摆弄的容器

答案 2 :(得分:1)

尽管std::vector< TcpSocket* > sockets_; 本身 const,但容器(即TcpSocket* const

这就是你获得非const扣除的原因。

答案 3 :(得分:0)

为什么你没有得到TcpSocket * const

虽然front()返回TcpSocket* const &,但auto推断为TcpSocket*

考虑一下:

double const & foo(); 
// ...
double const a = 4.0;
auto b = a; // valid, decltype(b) === double
double c = a; // valid, too
double d = foo(); // valid
auto e = foo(); // decltype(e) === double

无论如何你还要制作副本,为什么那份副本会const? 由于sTcpSocket * const,您无法获得任何有价值的信息。

为什么你没有得到TcpSocket const *

这只是因为你将TcpSocket*存储在向量中。 const的{​​{1}} ness确保存储的指针不会被更改(即您无法使front()指向sockets_.front()内的另一个TcpSocket但是Listener() - 指向的对象的正确性是由用户引起的。