std::size_t Instantiation
My first post, so please be kind :)
This code snippet is from the Poco library project:
void SyslogParser::parse(const std::string& msg)
{
// <int> -> int: lower 3 bits severity, upper bits: facility
std::size_t pos = 0;
RemoteSyslogChannel::Severity severity;
RemoteSyslogChannel::Facility fac;
parsePrio(msg, pos, severity, fac);
// the next field开发者_StackOverflow中文版 decide if we parse an old BSD message or a new syslog message
// BSD: expects a month value in string form: Jan, Feb...
// SYSLOG expects a version number: 1
if (Poco::Ascii::isDigit(msg[pos]))
{
parseNew(msg, severity, fac, pos);
}
else
{
parseBSD(msg, severity, fac, pos);
}
poco_assert (pos == msg.size());
}
I do not understand the role of std::size_t here. I thought that std::size_t would create an object (uint32 or uint64 depending on platform, etc.) which could hold the size of some other object. Is this understanding correct?
So what is happening here, then, is, we are creating an uint and (it appears) using it as a bitfield. If I am understanding what is being done, then I have to ask why? What is the advantage of producing an uint this way, as opposed to just declaring one?
Not questioning the author, just trying to understand what the advantage might be to take this route. Is there a speed or efficiency benefit?
I thought that std::size_t
would create an object (uint32 or uint64 depending on platform, etc.) which could hold the size of some other object. Is this understanding correct?
Yes
std::size_t
is a type that can be used to hold a size of any object in C/C++ program.
Usually functions use std::size_t
type as a standard way of receiving size of an object/type as an function parameter. Since the poco library functions are using std::size_t
as the type , the caller needs to create a parameter with the same type while calling these functions.
I think the comment in line 3 is misleading and should be removed.
pos
, as the name suggests, is the position in the string to which the string has been parsed already. At the end, the whole string must have been parsed, that's why all the parse*
functions (possibly) increment that variable. There are no bitfields involved here.
Maybe you thought that creating an object of type std::size_t
was an expensive operation, since many other types from that namespace are indeed possibly expensive, like std::string
, std::map
. But that isn't the case. std::size_t
is a very cheap data type.
The code should really look like this:
void SyslogParser::parse(const std::string& msg)
{
std::size_t pos = 0;
// <int> -> int: lower 3 bits severity, upper bits: facility
RemoteSyslogChannel::Severity severity;
RemoteSyslogChannel::Facility fac;
parsePrio(msg, pos, severity, fac);
...
From what I understand, the parsePrio()
function takes the pos
parameter by reference, so the calling code must use the exact same type the function is expecting. Moreover, the std::string::size()
function returns a value of type std::string::size_type
, which is usually std::size_t
. Using the same type as the value being compared to is also a good thing.
精彩评论