Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: ExMa2D [C++14] (feedback)  (Read 6997 times)

0 Members and 1 Guest are viewing this topic.

ramaskrik

  • Newbie
  • *
  • Posts: 45
    • View Profile
ExMa2D [C++14] (feedback)
« on: March 05, 2016, 05:24:40 pm »
Hi everyone!
This is not a project directly related to SFML, but it is intended to be compatible with SFML. Feel free to (re)move this topic if this is inappropriate.

Brief intro
ExMa2D is a tiny templated 2D vector and matrix library written in C++14. Currently only vector part is implemented, transform matrices are on their way.  It lives in Github repo LeviTaule/exma2D and is licensed under zlib/libpng license.

Motivation
I know, I should not be reinventing the wheel and stuff, but I think it is meaningful from educational perspective to write such a library (for me and, hopefully, for the others). Also, I am planning to write a 2D collision detection and response library in the future, so this may become handy.

Details
This library is a bit different than a usual vector library. It doesn't actually define a vector2D class, it implements some useful 2D vector operations on top of a vector library.
There are 2 requirements for such class, however:
  • It must have public x and y members, and they must be arithmetic
  • It must have the ability to initialize itself via argument list
For instance, these requirements are fulfilled by this class:

struct VectorF
{
    float x, y;
};

sf::Vector<T> is a valid candidate as well.

Example
(It doesn't do anything useful nor meaningful, just demonstrates the usage)
#include "exma2D/vector2D.hpp"
using namespace exma::vector;

struct VectorF
{
    float x, y;
};

constexpr VectorF vec{2.f, 5.f};
constexpr VectorF origin{0.f, 0.f};

constexpr auto crazy = -perpendicule(vec)
constexpr auto silly = project(crazy, vec) * 3;
constexpr auto crazy_silly = reflect(crazy, silly);
constexpr auto go_round = rotate(crazy_silly, origin, 180_deg);

auto length = len(go_round);
constexpr auto dot_product = dot(crazy, silly);

So what the hell I want from you?
Feedback.
I have noticed that people visiting SFML forums are cool folks and great programmers with a deep knowledge of modern C++. I would be very glad if you visited exma2D repository, skimmed through/read the code, maybe tried using it if you have some time, and then gave me some feedback on C++11/14 usage, library design (as this is my first open-source library), best practices and anything else you'd like to point out.

Eeeh....
Yes, I have been partially inspired to post here by this topic.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: ExMa2D [C++14] (feedback)
« Reply #1 on: March 05, 2016, 11:19:08 pm »
Looks cool, not intrusive and all that good stuff! :-)

A few comments, mostly nitpicking:

 - use `.tpp` or `.inl` instead of `.cpp` if the file is only meant to be included in a header file to implement templated features.
 - maybe rename `perpendicule` into an actual verb/noun? It feels weird but this is just my taste
 - but fix it at least.  ;) https://github.com/LeviTaule/exma2D/blob/master/include/exma2D/impl/vector2D.cpp#L150 should read `return {-vector.y, vector.x};`
 - pretty cool all those constexpr functions!
 - I'm wondering though if `distance` and `rotate` can really be constexpr...
 - there's a bit of duplication here and there; e.g. != and ==, or normalize and /.
 - you don't use has_quiet_NaN everywhere
SFML / OS X developer

ramaskrik

  • Newbie
  • *
  • Posts: 45
    • View Profile
Re: ExMa2D [C++14] (feedback)
« Reply #2 on: March 06, 2016, 05:03:12 pm »
Looks cool, not intrusive and all that good stuff! :-)
Thank you for your great feedback!

- use `.tpp` or `.inl` instead of `.cpp` if the file is only meant to be included in a header file to implement templated features.
I initially used .inl, but I ceased to do so for two reasons. The first one is that the different extension doesn't really bring anything. I don't and won't use non-template files, so it doesn't help in differentating template from non-template implementations. I also make clear in README the library is header-only. Second one is that a great number of editors don't support c++ syntax highlighting for .inl nor .tpp rightaway, but they do it for .cpp. I know this is changeable, but I don't want to make potential contributors to go find that, just because this library is header-only.
Those are the things I have considered when doing this decision, if there's more to this, I'll be glad to hear you out!

- maybe rename `perpendicule` into an actual verb/noun? It feels weird but this is just my taste
what is the actual verb? I wanted to keep the name as short as possible (make_perpendicular seemed too long to me) and perpendicule, despite being a made-up name clearly expresses what is the function about.

- but fix it at least.  ;) https://github.com/LeviTaule/exma2D/blob/master/include/exma2D/impl/vector2D.cpp#L150 should read `return {-vector.y, vector.x};`
good catch. I actually kind of screwed up doing the tests for this, so I didn't catch it myself. Thank you, I fixed it here.

- pretty cool all those constexpr functions!
 - I'm wondering though if `distance` and `rotate` can really be constexpr...
constexpr FTW! Again, thank you, fixed it here.
- there's a bit of duplication here and there; e.g. != and ==, or normalize and /.
You should seriously claim these commits, including this one. :)

- you don't use has_quiet_NaN everywhere
You have got one more commit to claim :)

Thank you! :D

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: ExMa2D [C++14] (feedback)
« Reply #3 on: March 06, 2016, 06:38:15 pm »
You're welcome!

Quote
Those are the things I have considered when doing this decision, if there's more to this, I'll be glad to hear you out!
I think your point stands. I'm myself more on the side of "take the time to setup your tools even if it means losing a day or two at it" so having *.tpp = *.cpp in my setup is not an issue (especially in Vim), but I'm well aware this point of view isn't shared by everyone.

Quote
what is the actual verb? I wanted to keep the name as short as possible (make_perpendicular seemed too long to me) and perpendicule, despite being a made-up name clearly expresses what is the function about.
I use `normal` in my codebase actually. It's a noun/adj, not a verb, but it makes it clear enough I believe. One could also expect `orthogonal` since it's mostly a synonym.
SFML / OS X developer

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: ExMa2D [C++14] (feedback)
« Reply #4 on: March 06, 2016, 08:44:04 pm »
I initially used .inl, but I ceased to do so for two reasons. The first one is that the different extension doesn't really bring anything. I don't and won't use non-template files, so it doesn't help in differentating template from non-template implementations. I also make clear in README the library is header-only. Second one is that a great number of editors don't support c++ syntax highlighting for .inl nor .tpp rightaway, but they do it for .cpp. I know this is changeable, but I don't want to make potential contributors to go find that, just because this library is header-only.
Those are the things I have considered when doing this decision, if there's more to this, I'll be glad to hear you out!

For what it's worth, I was a bit confused as to why the extension was .cpp at first. The reason I make the extension for template implementations is for compilers. A compiler will try to compile a .cpp unless set otherwise, which would give a fair amount of errors! That reason alone is why I would give a different extension, plus it's almost an unwritten rule to do so (if that's the correct wording...).

Otherwise, I like it! Looks well done to me!

Nerevar

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • XGM
Re: ExMa2D [C++14] (feedback)
« Reply #5 on: March 06, 2016, 08:58:22 pm »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: ExMa2D [C++14] (feedback)
« Reply #6 on: March 06, 2016, 09:57:20 pm »
Some comments:

The constraint that the class must have x and y members is unnecessary. Have a look at Boost.Geometry to see how is possible to write fully generic, yet simple to use code. Basically, the idea is:
namespace lib
{

// user can specialize this class to support other types
template <typename T>
struct vector_type
{
    static auto x(const T& v) { return v.x; }
    static auto y(const T& v) { return v.y; }
};

// convenience inside library, can also be in private namespace
template <typename T>
auto x(const T& v)
{
    return vector_type<T>::x(v);
}

}

Does SFINAE based on std::is_arithmetic actually bring an advantage? Types that don't provide the operations won't compile already, and you don't artificially limit what types users can work with.

Your functions take their parameters by value, leading to unnecessary copies.

The excessive type inference makes code a bit difficult to understand sometimes, and I'm not sure if it does what's intended all the time. Use it where it helps increase genericity, but in cases where you know the type, it may be helpful to write it down (even function-local as typedefs from metafunctions).

You can use macros to increase the readability of SFINAE. In places where it doesn't contribute to overload resolution, use static assertions instead of SFINAE, in order to create more meaningful error messages and not clutter the API.

Operators like unary - are not helpful inside your namespace, because they're not considered by ADL unless a library type is used as an argument. The only way to use them is to extract them to the global namespace, which is a very bad idea, because a function template without constraints accepts everything, and it will defeat implicit conversions of completely unrelated code.

The function std::abs() is part of the standard library, and it's possibly more efficient than yours. utils::compare() should have a better name.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

ramaskrik

  • Newbie
  • *
  • Posts: 45
    • View Profile
Re: ExMa2D [C++14] (feedback)
« Reply #7 on: March 06, 2016, 10:16:43 pm »
For what it's worth, I was a bit confused as to why the extension was .cpp at first. ..
Well, if it really confuses people I'll probably go with a different extension.
A compiler will try to compile a .cpp unless set otherwise, which would give a fair amount of errors!
I am a long time CMake Linux user and I have never had a problem with an eager compiler. I am sure CMake creates valid VisualStudio files as well, so I wouldn't see this as a problem.
Otherwise, I like it! Looks well done to me!
I am so happy you guys like it. This is my first serious attempt to make open-source project more could benefit from, so my happinness is even bigger. :-)
http://glm.g-truc.net/0.9.7/index.html
Of course, I do know about spectacular GLM library. However, GLM has slightly different use-cases than exma2d. GLM is a general math library with all the complexities it bears, while exma2d is a quick'n'dirty easy-to-use easy-to-dive-into strictly 2d library with a tiny codebase. GLM probably has got a lot of optimizations in terms of speed and efficiency, while exma2d's selling point is compatibilty with your already defined types and usage of C++14 (for instance, you no longer have to find out whether you need to pass degrees or radians, simply pass 90_deg or 100_rad and enjoy yourself. It is also clearer for anyone else reading the code after you.).

// edit: WOW Nexus, great feedback, I'll tackle your post tomorrow, until then, let me at least thank you for time :-)
« Last Edit: March 08, 2016, 07:53:10 pm by ramaskrik »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: ExMa2D [C++14] (feedback)
« Reply #8 on: March 06, 2016, 10:26:41 pm »
Well, if it really confuses people I'll probably go with a different extension.
It definitely does, it's common convention in C++ to use .cpp for translation units (= files that are compiled). And Hiura is also right that IDEs work according to that scheme.

for instance, you no longer have to find out whether you need to pass degrees or radians, simply pass 90_deg or 100_rad and enjoy yourself.
90 degrees are 100 gradians, but pi/2 radians.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: ExMa2D [C++14] (feedback)
« Reply #9 on: March 06, 2016, 10:52:05 pm »
Note that those last quotes were not from me but from dabbertorres.  ;)
SFML / OS X developer

ramaskrik

  • Newbie
  • *
  • Posts: 45
    • View Profile
Re: ExMa2D [C++14] (feedback)
« Reply #10 on: March 08, 2016, 08:22:21 pm »
Sorry for the late response, have been a bit busier than expected. Anyway, here it is.

Some comments:

The constraint that the class must have x and y members is unnecessary. Have a look at Boost.Geometry to see how is possible to write fully generic, yet simple to use code. Basically, the idea is:
namespace lib
{

// user can specialize this class to support other types
template <typename T>
struct vector_type
{
    static auto x(const T& v) { return v.x; }
    static auto y(const T& v) { return v.y; }
};

// convenience inside library, can also be in private namespace
template <typename T>
auto x(const T& v)
{
    return vector_type<T>::x(v);
}

}
An excellent suggestion! Thanks, I will work on this in the near future.

Does SFINAE based on std::is_arithmetic actually bring an advantage? Types that don't provide the operations won't compile already, and you don't artificially limit what types users can work with.
Yeah, kinda. I am using std::numeric_limits<T>::epsilon() in the compare(), which doesn't make it an artificial limitation, but a real one. Of course, I don't call compare() in every function, do you think I should remove this constraint from those functions? Or should I implement compare() with a fixed allowed deviation?
Your functions take their parameters by value, leading to unnecessary copies.
Thanks, fixed.

The excessive type inference makes code a bit difficult to understand sometimes, and I'm not sure if it does what's intended all the time. Use it where it helps increase genericity, but in cases where you know the type, it may be helpful to write it down (even function-local as typedefs from metafunctions).
Not really great with terminology, do you mean the unnecessary auto with decltypes? If so, it has been fixed as well (in the commit above).

You can use macros to increase the readability of SFINAE. In places where it doesn't contribute to overload resolution, use static assertions instead of SFINAE, in order to create more meaningful error messages and not clutter the API.
I don't really see how would this help. Would you explain yourself a bit more clearly with an example? (I am obviously a beginner in these manners, so I tend to be a bit annoying with my lack of knowledge. Feel free to ignore this, if you find it annoying)

Operators like unary - are not helpful inside your namespace, because they're not considered by ADL unless a library type is used as an argument. The only way to use them is to extract them to the global namespace, which is a very bad idea, because a function template without constraints accepts everything, and it will defeat implicit conversions of completely unrelated code.
This is meant to be like this. I don't want to be invasive, so if user has already defined basic operators, and only wants to use higher-level functions, (s)he is free to do so.
I think I have imposed pretty strict rules on types what the functions can take. I can't imagine a scenario where a function would be inadequately generated for unwanted types. Would you mind providing such a scenario?
The function std::abs() is part of the standard library, and it's possibly more efficient than yours.
It surely is. But it is not constexpr by standard (g++ does implement it as constexpr, but clang doesn't.) Should I give up constexpr in abs, which means in compare as well, which means in a bunch of other functions as well?
utils::compare() should have a better name.
True. What would you suggest? is_equal?



It definitely does, it's common convention in C++ to use .cpp for translation units (= files that are compiled). And Hiura dabbertorres Yeah, my bad. Sorry. is also right that IDEs work according to that scheme.
Fixed. Using .tpp from now on.

90 degrees are 100 gradians, but pi/2 radians.
I didn't mean to imply that 100 rad is 90 deg (although it could have been understood like that, good catch!), I just used arbitrary values. Anyway, didn't know about gradians, thanks for the info!

Note that those last quotes were not from me but from dabbertorres.  ;)
Sorry, using phone is not the best way how to write comprehensive posts. It has been fixed. :)



I have missed a part of your previous post, Hiura, so here's my response:
I use `normal` in my codebase actually. It's a noun/adj, not a verb, but it makes it clear enough I believe. One could also expect `orthogonal` since it's mostly a synonym.
I like to use verb as function names, and normal could be mixed up with normalize, and the similarity doesn't really contribute to IntelliSense as well. Also orthogonize is no better :) So even when it's a made up name, IMHO it does the job the best. Just my preference, really. :) (want to be as transparent as possible :) )
« Last Edit: March 08, 2016, 08:29:15 pm by ramaskrik »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: ExMa2D [C++14] (feedback)
« Reply #11 on: March 08, 2016, 09:32:48 pm »
Constraints and epsilon: it's possible that a user may still use a subset of your features without needing epsilon, or that he specialized numeric_limits himself. In the end it depends on what you want to express in your API. But those are minor things, don't spend too much time on such things until you get actual feedback from users.

Yes, type inference means that the compiler can infer/deduct the type from expressions, i.e. auto and decltype. In general, even though C++11 introduced these keywords and C++14 made them more powerful, using a feature everywhere just because it's possible has never been the most sensible approach ;)

You use this SFINAE expression
typename =
std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>,
  typename =
std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().y)>{}>
a lot of times. Using macros is just a matter of reducing code duplication while at the same time increasing readability. Regarding those constraints in particular, they could also be omitted entirely, see above.

Generally speaking, if you see yourself copy/pasting a lot, always ask if that's necessary. C++ is extremely powerful with respect to avoiding boilerplate code, and sometimes even resorting to macros is worth it.

Your operators cannot be used (no ADL) unless exported into the global namespace. You're right that SFINAE constrains the accepted types, but it's still not possible to selectively enable only specific types -- all classes that have public x and y members of arithmetic type are accepted. You may think that these are vectors anyway, but what about 3D vectors, or if the user has another vector class? I'd rather base a constraint on specialization of a library-specific traits template (like vector_type mentioned in my last post). With template operators, you have to be very careful.

To be honest, "perpendicule" sounds... a bit ridiculous :P and looks like a French word. "Orthogonize" is indeed not better, but "orthogonalize" is, yet it's associated with a related concept in linear algebra and might thus not be intuitive. Don't hesitate to make function names expressive, i.e. "makePerpendicular".

It's usually a good idea to name functions after verbs, but in this case, it could express that a function changes the object. In my library Thor, I'm using nouns as well, e.g. "perpendicularVector", to make clear that a new object is created -- just like constructors are nouns.

The constexpr argument is true, but: 1. are you sure that many people will benefit from compile-time evaluation, and 2. that modern compilers are not already able to recognize and optimize intrinsics like abs() when they're invoked on constant expressions? I would have a look at Assembly outputs before optimizing prematurely. Because the first thing everybody asks himself when he sees custom abs() is "what's wrong with the standard one".
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: ExMa2D [C++14] (feedback)
« Reply #12 on: March 08, 2016, 09:55:51 pm »
Yes, type inference means that the compiler can infer/deduct the type from expressions, i.e. auto and decltype. In general, even though C++11 introduced these keywords and C++14 made them more powerful, using a feature everywhere just because it's possible has never been the most sensible approach ;)

You shouldn't read my code then.  :P

More seriously, I'm also used to code in Scala where you use everywhere the compiler's inference ability and use the equivalent of auto everywhere -- in fact it's very rare to have to add an extra annotation for types. And in C++, modern tools are able to give the type of variable declared using auto if needed (I'm specifically referring to YouCompleteMe for Vim). Additionally, type inference advocates claim -- and I believe this is true -- that it can actually reduce maintenance costs.

But I agree with your *general* note regarding features usage.
SFML / OS X developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: ExMa2D [C++14] (feedback)
« Reply #13 on: March 08, 2016, 11:13:59 pm »
A few thoughts on type inference...

What I have noticed in C++, is that partly because of implicit conversions between arithmetic types, people often don't know or care what types they actually deal with. If you look at typical C++ code, you won't find it annotated with f (float) or u (unsigned int) postfixes, because it's not strictly necessary if the type stands next to it. Many people don't even know that adding two shorts doesn't result in a short. Migrating code from
for (std::size_t i = 0; i < size; ++i)
to
for (auto i = 0; i < size; ++i)
however changes semantics in a non-obvious way. Mostly, this doesn't matter, but there are cases where it does -- especially when the type decides between different code paths, e.g. in overload resolution.

You're totally right that type inference can be extremely helpful, as it can reduce boilerplate code and maintenance in general, e.g. with simplified type migration across functions. This is especially nice when dealing with tempalte metaprogramming, where a lot of code is required to express simple things. But also for iterator declarations and other clutter where the details aren't interesting.

Propagating the type information across multiple indirections is a double-edged sword: it helps migrate types (changing it at the source will make clients adapt automatically), but it's also a source of error (one client behaves differently now). Also, it makes error messages more difficult to interpret, because the error may manifest completely elsewhere than its source. And it's not as if template metaprogramming error messages have been easy to read so far ;) what I mean is: types can act as an interface, and as such as a barrier between decoupled modules. Whatever happens on one side doesn't affect the other; a core principle in software development. And this is not just important from a design perspective; it's also something to consider given C++' header/implementation separation. Functions using type inference in their signature or return type are essentially templates and force the implementation to be located in the header.

While many people argue that type inference helps hide implementation/language details unimportant to the developer (the types), it's sometimes overlooked that in certain situations, types are the central part of code. This applies less to generic template libraries, but more to algorithm-heavy programming, where the type decides what data structure is used and how efficient different operations on it are. For example, when dealing with STL containers, I'm usually interested if it's a vector or deque or list, but not in the verbatim declaration of its iterator.

What we are usually interested in are not types, as they're declared, especially because C++ with its generic programming paradigms makes them rather wordy. However, what I as a programmer am always interested in is the type category, which expresses its semantics. Am I dealing with a container, with a number, with a string, with a pointer? C++ type inference is all-or-nothing, you hide the entire information associated to a type with it. Some can be compensated through expressive variable and function names, but not always.

Concepts are a big step in that direction. They're essentially what I'm referring to with type categories: they express what a type is "like", i.e. provide a description of its capabilities and semantics, but don't dictate its concrete declaration.

That's why I would argue that for average C++ code (i.e. not heavy generic programming), a page full of auto keywords is more difficult to read than a page with mixed explicit and inferred types. Explicit where types are short and carry crucial semantics, inferred where they're verbose noise. Because even in the presence of IDEs and static analysis tools, one still has to hover over types, i.e. it's not as easy to see the big picture.



Anecdote: Yesterday, 7 years ago, I started a discussion about C++11 features, among others type inference, with some of the brightest C++ minds in the German speaking community. I was skeptical regarding some new features -- and while I've changed quite a few of my views after using those features, some of my anticipations have remained to this day.

I'm amazed again and again by the fact that C++11 is now half a decade old, and that we started talking about it already years before...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: ExMa2D [C++14] (feedback)
« Reply #14 on: March 09, 2016, 12:04:22 pm »
maybe a mod should split this topic if people want to continue the discussion...

There's quite some interesting points there!

What I have noticed in C++, is that partly because of implicit conversions between arithmetic types, people often don't know or care what types they actually deal with.
Yes, that's true. I personally don't really like those implicit conversions (because they're far from trivial in some cases) and that's why I rely on compiler warnings to avoid those. Yet, your point stands: not everybody has the luxury to work exclusively with people aware of the problem derived from implicit type conversions and capable of settings their tools to "fight" these.

But again, I'm biased in that regard because I'm used to other languages where you can easily "extend" types and therefore implicit conversions is a top-level feature of the languages and doesn't seem to bother people -- on the contrary in fact. (See Scala implicit mechanism, which is huge, or Objective-C categories.)

Maybe we can see a difference in the kind of application developped where type inference is useful or harmful. Like you said, when it comes to integers manipulation (or float for that matter), it's better to be aware of everything, but when we are farther from those primitive types manipulation, one might actually not care about the concrete type of (e.g.) a sequence (a vector, list or something custom? nah, that the same to me) -- except, as you said, when it comes down to critical code that has to be optimised:

This applies less to generic template libraries, but more to algorithm-heavy programming, where the type decides what data structure is used and how efficient different operations on it are. For example, when dealing with STL containers, I'm usually interested if it's a vector or deque or list, but not in the verbatim declaration of its iterator.

Propagating the type information across multiple indirections is a double-edged sword: it helps migrate types (changing it at the source will make clients adapt automatically), but it's also a source of error (one client behaves differently now).
Yes, but this is not inherent to type inference: you can have exactly the same issues with "regular" changes (improving an implementation yet breaking a contract; change the semantics of an existing type; ...). So I wouldn't held this against `auto` but rather against a bad developer.  ;)

Functions using type inference in their signature or return type are essentially templates and force the implementation to be located in the header.
In that regard, I totally agree: one shouldn't move the implementation to a header file exclusively for using `auto` for return type!


What we are usually interested in are not types, as they're declared, especially because C++ with its generic programming paradigms makes them rather wordy. However, what I as a programmer am always interested in is the type category, which expresses its semantics. Am I dealing with a container, with a number, with a string, with a pointer? C++ type inference is all-or-nothing, you hide the entire information associated to a type with it. Some can be compensated through expressive variable and function names, but not always.
Actually, I believe this to be somewhat untrue in C++ and will probably be less true when Concepts are finally standardised: you can already annotate, using `auto`, whether a variable is a value, a pointer or a reference (or constant):

for (auto  v : seq)
for (auto* p : seq)
for (auto& r : seq)

(And of course this works in any place where you can declare a variable with auto.)


That being said, I join you when you say that a wall of auto is harmful. But doesn't this kind of code usually suffers from other issues as well (such as functions being too long and obscure code patterns being used)?


Ho, and we will probably still discuss this in 7 years. ;-)
SFML / OS X developer

 

anything