如何将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_
作为第一行代码,无法编译,基本上说const
是const
。
它的工作原理是有道理的,但这里显然有更多的事情,而不仅仅是在一个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";
}
}
。
答案 0 :(得分:3)
sockets_
内的 Listener
为const
。让我们来看看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
?
由于s
为TcpSocket * const
,您无法获得任何有价值的信息。
TcpSocket const *
:这只是因为你将TcpSocket*
存储在向量中。 const
的{{1}} ness确保存储的指针不会被更改(即您无法使front()
指向sockets_.front()
内的另一个TcpSocket
但是Listener()
- 指向的对象的正确性是由用户引起的。