Jump to content
  • Advertisement
Sign in to follow this  
DevFred

x.begin(), x.end()

This topic is 3604 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When using STL algorithms, I often find myself typing stuff like
accumulate(a.begin(), a.end(), 0);
for_each(b.begin(), b.end(), foo);
remove_if(c.begin(), c.end(), bar);
Today I thought to myself: why not use the preprocessor to make things clearer?
#define ALL(x) x.begin(), x.end()

accumulate(ALL(a), 0);
for_each(ALL(b), foo);
remove_if(ALL(c), bar);
As long as x is just a variable, I don't see any problems with it. Is this a reasonable use of the evil preprocessor? Maybe there's even a real solution I don't know about? Discuss!

Share this post


Link to post
Share on other sites
Advertisement
Let's be honest, you are making your code more unclear as well as sacrificing type safeness in order to save a little extra typing.

Share this post


Link to post
Share on other sites
Using the preprocessor to obscure and de-idiomize code just because you are lazy is not generally considered to be a good idea.

Share this post


Link to post
Share on other sites
No, it's not. If you really think it's worth it, you should be able to make templated forms that do the same thing while being infinitely more robust.

Share this post


Link to post
Share on other sites
Quote:
Today I thought to myself: why not use the preprocessor to make things clearer?


Why not use language itself? C++ in general has no overhead for syntactic sugar, especially when dealing with templates.


template < class Container, class T >
void accumulate(Container & c, T t)
{
accumulate(c.begin(), c.end(), t);
};


accumulate(a, 0);

Or something....

Share this post


Link to post
Share on other sites
Taking for_each(ALL(b), foo) as an example, wouldn't this be better?:

template <class InputIterableContainer, class UnaryFunction>
inline UnaryFunction for_each(InputIterableContainer & c, UnaryFunction f)
{
return std::for_each(c.begin(), c.end(), f);
}

Share this post


Link to post
Share on other sites

#define ALL(x) x.begin(), x.end()

class Foo
{
public:
void AddValue(int i)
{
m_values.push_back(i);
}

std::vector<int> GetValues() const
{
return m_values;
}

private:
std::vector<int> m_values;
};


void printFoo(Foo f)
{
std::copy(ALL(f.GetValues()), std::ostream_iterator<int>(std::cout));
}




Spot the bug.


Also, check out boost::range.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
*** Source Snippet Removed ***
Spot the bug.


getValues() returns a copy & the pre-processor makes x == f.getValues() instead of just the vector, so the .begin() and the .end() are iterators from different vectors. ZOMG, what do i win? [smile]

-me

Share this post


Link to post
Share on other sites
I believe the problem can be generalised by saying it's an ill-behaved macro because it evaluates its arguments more than once.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
I believe the problem can be generalised by saying it's an ill-behaved macro because it evaluates its arguments more than once.


Writing macros in such a way that these issues can be avoided can be a headache, especially since at first glance, it looks just fine. The reality is that there's no reason for the riskier macro when saver solutions exist, so why even take the risk? A macro is an absolute last resort for me. Especially when you consider that to avoid clashes, a better name than "ALL" is required. You might need something like:


#define STL_ALGORITHM_HELPER_ALL(x) x.begin(), x.end()

...

accumulate(STL_ALGORITHM_HELPER_ALL(a), 0);



Once you do that, the supposed reduced typing of the macro is proven to be a fallacy and the macro loses on all accounts.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!