What's your preferred way of returning a list of items?

J

James Kanze

Well, I understand that there are shops where templates are
prohibited by local coding guidelines. I would suppose they
have those rules in place for good reasons. Admittedly, under
those circumstances, using the OutIter signature is not
feasible.
I would, however, maintain that templates _should_ be fine for
many projects.

They're fine in certain places on most projects. On the other
hand, you don't want to make everything a template. If the code
necessary to calculate the values to fill the list, for example,
is a couple of hundred lines, you don't really want it in
a template:).
I do see that they interact poorly with the C++ model of
separate compilation and source code file inclusion: taken
together, the package does not really scale all that well.
I am just not certain at which point scaling becomes a valid
reason to ban templates.

The ban is relative. There are places in a lot of applications
where you don't want templates. And there are others where
they're acceptable. But in general, I wouldn't use a template
unless there was an actual requirement to support several
different types. I might write the code using a back iterator
into a vector, with the idea that if the need arose, I could
easily convert it into a template, but until the need arose, I'd
stick with the non-template form. And if the function were not
at the lowest, most stable layer, I'd avoid the template,
period.
 
D

DeMarcus

I avoid writing functions that are getters, copiers or even worse ...
setters, because these indicate lousy design. I usually try my best to
have interface that allows operations that make sense to do with the
objects of given type and not interface that allows mechanical
setting, getting and copying of the properties of objects.

My functions that are still getters are nouns (remove "get" prefix,
once situation enforces to be lousy, go maximum) and are either
returning copies or const references. My functions that fill their
parameters with a copy of internal data start with "copy" and i call
them copiers. Setters are also nouns (no "set" prefix; have to be java
so go maximum) but return void and take const reference as parameter.

I'm also very much into name convention and would gladly remove "get"
from function names. However, I've realized that those prefixes make the
code easier to read sometimes. Take this example for instance.

void setItem( SomeItem& item );

or

void addItem( SomeItem& item );


The prefix quickly tells you that if the first function is present, the
class can only have one item. But if the second function is present, the
class can have several items. Just having

void item( SomeItem& item );

would not provide information whether the class can have one or several
items.

How do you usually deal with such prefixes?
 
J

James Kanze

[...]
I'm also very much into name convention and would gladly
remove "get" from function names. However, I've realized that
those prefixes make the code easier to read sometimes. Take
this example for instance.
void setItem( SomeItem& item );

void addItem( SomeItem& item );
The prefix quickly tells you that if the first function is
present, the class can only have one item. But if the second
function is present, the class can have several items. Just
having
void item( SomeItem& item );
would not provide information whether the class can have one
or several items.
How do you usually deal with such prefixes?

The way the coding conventions where I work require:).

My own preference makes a distinction: if the class conceptually
contains a mutable data member, then I'll provide the two
functions:
Item item() const;
void /* or Item */ item(Item newValue);
(It's occasionally useful to return old value, in case the
client code wants to restore it later.) This idiom is IMHO only
appropriate when the class does represent data. Otherwise, it's
get and set (or add).

But as I said, the local conventions take precedence.
 
A

Alf P. Steinbach

[...]
I'm also very much into name convention and would gladly
remove "get" from function names. However, I've realized that
those prefixes make the code easier to read sometimes. Take
this example for instance.
void setItem( SomeItem& item );

void addItem( SomeItem& item );
The prefix quickly tells you that if the first function is
present, the class can only have one item. But if the second
function is present, the class can have several items. Just
having
void item( SomeItem& item );
would not provide information whether the class can have one
or several items.
How do you usually deal with such prefixes?

The way the coding conventions where I work require:).

My own preference makes a distinction: if the class conceptually
contains a mutable data member, then I'll provide the two
functions:
Item item() const;
void /* or Item */ item(Item newValue);
(It's occasionally useful to return old value, in case the
client code wants to restore it later.) This idiom is IMHO only
appropriate when the class does represent data. Otherwise, it's
get and set (or add).

But as I said, the local conventions take precedence.

It seems that local conventions often can get in the way of applying conventions
that can reduce bug rates, improve clarity and so on.

The underlying assumption of that kind of micro-management seems to be that
programming is a pure assembly activity, "canned programming", i.e. doing the
same kind of thing as before, just repeating the same ole' patterns ad nauseam.

E.g. in C++ there's a nice little triad of functions, where the presence or
absence of a "get" prefix improves readability and signifies which one:

void getValue( Value& v ) const
{
Value result;
// Whatever.
result.swap( v );
}

Value value() const
{
Value result;

getValue( result );
return result;
}

void setValue( Value const& v )
{
// Whatever
}

But in some context pure "value" also for the setter is clearly best wrt.
readability, e.g. for the named parameters idiom (with chaining of calls).

So if there is a convention requiring one or the other, then it would in my view
get in the way of a sensible context-dependent choice.


Cheers,

- Alf
 
Ö

Öö Tiib

I'm also very much into name convention and would gladly remove "get"
from function names. However, I've realized that those prefixes make the
code easier to read sometimes. Take this example for instance.

void setItem( SomeItem& item );

or

void addItem( SomeItem& item );

The prefix quickly tells you that if the first function is present, the
class can only have one item. But if the second function is present, the
class can have several items. Just having

void item( SomeItem& item );

would not provide information whether the class can have one or several
items.

How do you usually deal with such prefixes?

I avoid names that say nothing like "item", "data", "info", "config",
"manager", "counter".
I avoid merging the bad things further into bigger names like
"dataItem", "infoManager", "getConfigData".
Additionally i avoid parts of names that indicate (and so bind to, or
lie about) the underlying type like "enum", "vec", "list", "map".

My member functions are usually verbs. As hypothetical example say I
have Person class. I prefer member functions like marry(),
giveBirth(), adopt(), not addChild(). When the member functions are
nouns then that means these are getters for information.
Person may have getters like firstName(), familyName(), children()
etc. I avoid getListOfChildren() member function. It somewhat breaks
things. "getListOfChildren()" sounds like returning std::list<Person>,
"children()" sounds like returning container of Person::Children
interface type.

About setters i can say why i do not like them. I prefer that for
example when Person object "Robert Smith" marry() with Person object
"Mary Hunter" then there is immediately way to indicate if she is
after that event still "Mary Hunter" or "Mary Smith" or "Mary Smith-
Hunter". I prefer that interface of marry() is extended with possible
details if there was no such way in original design.

Some urgent maintenance may however add family name setter to Person
and make it possible for anyone to hack with family name of poor Mary.
When such setter is unavoidable i prefer that it is
familyName(string), overload to getter.

Like Alf said in else reply it may depend on context what names give
most readable results. For my style it is usually the shortest form
made free of meaningless and detail-revealing ballast. I no way
enforce it upon anybody or suggest to add it into style guide. I just
took it and did stick to it over years. Usually it is someones work
that my software supports. So when they talk about it i write
carefully down the professional slang they use, especially verbs and
nouns and reuse these in my code.
 
D

DeMarcus

Aah, but if you do anything with that text other than simply write it
out verbatim, you've got behavior leaking all over your application when
you process the item. By decomposing at this point I always end up with
some abastractions that I can reuse in multiple places.

I would even start looking at where the data for this vector is coming
from, which is probably some stream, then I'd develop the grammar to
parse that data directly into domain entities. This always ends up using
less memory, fewer cycles and is more flexible with less coupling.

Yes, good point. Thanks!
 
D

DeMarcus

I avoid names that say nothing like "item", "data", "info", "config",
"manager", "counter".
I avoid merging the bad things further into bigger names like
"dataItem", "infoManager", "getConfigData".
Additionally i avoid parts of names that indicate (and so bind to, or
lie about) the underlying type like "enum", "vec", "list", "map".

My member functions are usually verbs. As hypothetical example say I
have Person class. I prefer member functions like marry(),
giveBirth(), adopt(), not addChild(). When the member functions are
nouns then that means these are getters for information.
Person may have getters like firstName(), familyName(), children()
etc. I avoid getListOfChildren() member function. It somewhat breaks
things. "getListOfChildren()" sounds like returning std::list<Person>,
"children()" sounds like returning container of Person::Children
interface type.

About setters i can say why i do not like them. I prefer that for
example when Person object "Robert Smith" marry() with Person object
"Mary Hunter" then there is immediately way to indicate if she is
after that event still "Mary Hunter" or "Mary Smith" or "Mary Smith-
Hunter". I prefer that interface of marry() is extended with possible
details if there was no such way in original design.

Some urgent maintenance may however add family name setter to Person
and make it possible for anyone to hack with family name of poor Mary.
When such setter is unavoidable i prefer that it is
familyName(string), overload to getter.

Like Alf said in else reply it may depend on context what names give
most readable results. For my style it is usually the shortest form
made free of meaningless and detail-revealing ballast. I no way
enforce it upon anybody or suggest to add it into style guide. I just
took it and did stick to it over years. Usually it is someones work
that my software supports. So when they talk about it i write
carefully down the professional slang they use, especially verbs and
nouns and reuse these in my code.

Thanks for your input. I'll spend more time finding a proper naming
convention.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top