• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Alessio1989

So... C++14 is done :O

85 posts in this topic

And there I haven't even given every C++11 feature a spin yet.

IMHO, you missed the best "new" feature in that list:
- Binary literals (yay, finally!)
2

Share this post


Link to post
Share on other sites
Any hope/wish/desire for the next standard?

Compile time reflections (and being able to process them)

Edited by imoogiBG
1

Share this post


Link to post
Share on other sites
Keep in mind that C++ also now has Technical Specifications, which are extensions to the language or library that are standardized in functionality but not required. e.g., Reflection is likely to land in a TS, meaning that any compiler that implements it will implement it in a compatible way but compilers can still be C++17 compliant without supporting it. Think of them sort of like OpenGL extensions, but each with the clear intent to roll into the proper standard once they've been hammered on by the community and unforeseen design mistakes are sorted out.
0

Share this post


Link to post
Share on other sites

 

 I still think the range-based loops were unnecessary. 

 

Can you elaborate more? Personally I feel it is alot more readable.

2

Share this post


Link to post
Share on other sites

Glad to see C++14 finalized. I've already been making use of it as I tend to use GCC and increasingly Clang/LLVM.

 

Concepts are nice, but what I think C++ desperately needs is modules, and I don't think it can wait till C++17. We need modules yesterday. Besides that, I personally would like to see a standardized ABI for C++, as purposed by N4028, as that is something which I personally think is important.

0

Share this post


Link to post
Share on other sites

Range based loops, however, added nothing. The old method was still there, and it is still there. The result is that instead of the traditional 'minimalist' approach, there is duplication. It did not enable any new thing. It did not add a feature. It did not do something that could not be trivially done before. It obscures details, adds an additional interface, but doesn't add any functionality. It is syntactic sugar, it is language bloat.

 

Range-based for loops basically implemented for-each loops, which in my book is good enough to warrant it. In my personal opinion, I totally love them. Sure, you could possibly do the same thing with a macro before, but its much cleaner that way:

std::vector<Class*> vValues;

for(auto pValue : vValues)
{
    pValue->DoSomething();
}

for(auto itr = vValues.begin(); itr = vValues.end(); ++itr)
{
    (*itr)->DoSomething(); // i totally loved having to do that itr-dereferencing as well before on vector<pointer>
}

I see your argument about not implementing something totally new, but fail to see why this is a bad thing. Everything that allows you to write code faster and cleaner at the same time, while not being forced upon, is IMHO a decent thing. Why would anyone ever prefer to write the loop the second way (and thats the nice version already using "auto")? Unless you want to delete something from the loop, yeah, quess that counts.

Edited by Juliean
2

Share this post


Link to post
Share on other sites


Why would you write the loop the 2nd way when you have std::for_each and lambda functions?

 

You don't,  unless you don't know about std::for_each like I did.

std::vector<Class*> vValues;

std::for_each(vValues.begin(), vValues.end(), [] (Class* pValue)
{
     pValue->DoSomething();
});

I quess that works, especially if you make a wrapper function that removes the need for always specifiying "begin/end" when all you want is the full range. Quess I still prefer range-based loops, just a little more explicit than this version. (I do have to admit that this changes things a little bit at least, always more to learn :D).

0

Share this post


Link to post
Share on other sites

nullptr is just about the only feature of C++11 I actually use (though I was fine with the plain-old NULL). Ctr delegation is also nice, but again - syntactic sugar.

Seems to me like C++11/14 features are mostly beneficial if you are writing an STL like library (See Bjorn's FAQ, a lot of the examples are STL related).

 

I agree with frob - C++11 and C++14 are moving away from the minimalist approach, which isn't a good thing (and don't get me started on the dangers of 'auto').

2

Share this post


Link to post
Share on other sites

Why would you use any of those examples when the idiomatic version from the past 2 or 3 decades still works, is understood by everyone, and generates the same ASM? laugh.png

 

Lots of things from the past still works, which still doesn't mean its the most optimal way of doing things. One can still send letters for written communication, but using online services is just a tad bit quicker ;)

 

Also while probably most people understand the old version, doesn't mean its easy to read. In fact, let alone the different variants, like having to explicitely store the end-condition and post/pre-increment validates a fixed solution for me.

 

More prone to error comes to mind, too. Especially for nested loops. Have lost count of how many times I mistakenly incremented the wrong variable or some stuff like that.

 

And as I already mentioned: Less code to type each time around - for the cost of what? That someone who hasn't seen this kind of loop might have to get used to reading it? From my personal view, the range-based loop is way easier to read, especially if you are new to the language - would anyone want to argue that a beginner would have an easier time with the old explicit loop?

 

Although generally, based on the old/new discussion, the question shouldn't be "what do I gain by using the new way" but rather "what do i lose by doing so?". People tend to favor that which they are used to, so unless there is a huge loss and virtually no gain for doing it with a new option, I'd say pick the new one.

 

EDIT:


nullptr is just about the only feature of C++11 I actually use (though I was fine with the plain-old NULL). Ctr delegation is also nice, but again - syntactic sugar.

 

Varadic templates are also very useful. Reduces code complexity on things like signal/slots, delegates etc... by a drastic amount, also allowing for perfect forwarding.

Edited by Juliean
2

Share this post


Link to post
Share on other sites

Although generally, based on the old/new discussion, the question shouldn't be "what do I gain by using the new way" but rather "what do i lose by doing so?". People tend to flavor that which they are used to, so unless there is a huge loss and virtually no gain for doing it with a new option, I'd say pick the new one.

 

I actually think the question is "in how many ways can someone else screw-up the code?". And in C++11 the answer is a lot more then with the "old" C++.

If you are an experienced programmer, who understands the pros and cons of the new feature - then use whatever you want. The problem is that there are way too many inexperienced programmers who (unintentional?) abuse things, or will understand what you are doing.

 

Take 'auto' for example - it's great when used with caution (and very very sparsely). But I saw some programmers who just decided that it would be great to use it as much as possible (even a very experienced one), regardless of minor things like code readability and type safety.

[EDIT] - 'type safety' should be 'compile time type checks'.

 

C++ is not a scripting language, nor is it a high-level abstracted language with powerful RTTI like Java. And it shouldn't be. Most of the new features seem to solve very minor problems and do not provide great benefit over the legacy C++.

Edited by N.I.B.
0

Share this post


Link to post
Share on other sites
Any hope/wish/desire for the next standard?

Compile time reflections (and being able to process them)

Or, at least introspection (I can see how reflection may be harsh on the implementator side, but introspection is just about accessing something the compiler already knows anyway). I would already be totally happy with that.

 

Most importantly, I'd like being able to ask an enumeration for the number of elements/members inside it, in a straightforward, no-hack, robust way (robust insofar as "holes" in enumeration values don't give you a wrong count as the typical "workaround" does). But of course there are plenty of other things that you may wish to query, which the compiler readily knows (and which don't involve complex program-rewriting voodoo on the implementor side).

 

I'd rather like to see this than things like networking or filesystem stuff, which are usually "nasty low level stuff" anyway unless you only want to do the most basic things. On the other hand, they're hard to get right and wrap into one standard (unless you leave out most of it, or you do like the proposal does "implementation does not need to support blah blah if the system does not") and they're things that constantly change. Some filesystem support hard links and some don't. Some support long names, attributes, alternate streams, and terabyte-sized files, and transactions, others don't. Some have a single root, others don't. Maybe in a few years from now the hierarchy will look radically different from anything we have now, who can tell?

Once upon a time, 20 years ago, BeOS had no filesystem at all, but merely a full-disk relational database (which would also store the "files"). Granted, that was a failure, but for economic reasons, not because it didn't work well -- it certainly worked, and it was darn cool. It might very well be that 10 or 20 years from now, all filesystems look like this, it only takes someone to pick up the old idea and produce a working, performant implementation on a mainstream system. Then what would I do with my C++ filesystem code?

0

Share this post


Link to post
Share on other sites

Take 'auto' for example - it's great when used with caution (and very very sparsely). But I saw some programmers who just decided that it would be great to use it as much as possible (even a very experienced one), regardless of minor things like code readability and type safety.

 

I'm kind of uncertain about 'auto', as it can truly screw over beginners, but I also think that it can in fact even increase readability. E.g:

void Saver::SaveMethod(xml::Node& node, const ExecutionUnit& unit, bool isMain)
{
	xml::Node* pTriggersNode = nullptr;
	if(isMain)
		pTriggersNode = &node.InsertNode(L"Trigger");

	auto& commandNode = node.InsertNode(L"Commands");

	auto& mEvents = unit.GetEvents();
	if(!mEvents.empty())
	{
		std::map<unsigned int, const Command*> mSorted;
		for(auto& event : mEvents)
		{
			mSorted.emplace(event.second->GetId(), event.second);
		}
		
		// ...
	}
}	

Does it really matter for the reader which type "commandNode"  and "mEvents" is? The names & assignments already clearly state which purpose this variable has, and whether its an xml::Node or an xml::WriteNode or so don't really help on that. For that reason, I would even go as far as to say that in this case it makes it more readable.

 

Type-safety is always there with auto, unless you are talking about a special case, its just that the type is "invisible" and will adjust to what is assigned to the variable, but compile-time type checks still apply.

 

 



What if I only want to DoSomething on elements that pass some test?

for (size_t i = 0, end = vValues.size(); i != end; ++i) {
if (some_test(*vValues[i]))
vValues[i]->DoSomething();
}

 

You can do that with the range-based loop too.

for(auto pValue : vValues)
{
	if(some_test(pValue))
		pValue->DoSomething)
}

Loop-modification is really the only perfect reason where range-based loops totally don't work.

Edited by Juliean
0

Share this post


Link to post
Share on other sites

Take 'auto' for example - it's great when used with caution (and very very sparsely). But I saw some programmers who just decided that it would be great to use it as much as possible (even a very experienced one), regardless of minor things like code readability and type safety.

One of those programmers who decided that using auto as much as possible is Herb Sutter. It is a misconception that auto makes your code worse or unsafe in any way.

 

It's not "just any type" like in some scripting languages, not at all. auto requires that the type is exactly known, and it results in a precisely defined type (which you don't see in your code, but the compiler knows it!) that is properly checked as if you typed it out by hand. It has hardly any disadvantages (if any), but lots of advantages. And those are not only that it's less work to type auto than to type std::foo<bar<baz, bat>>::blah::iterator when you actually don't care about what the type is exactly, as long as it's correct.

2

Share this post


Link to post
Share on other sites
A lot of people use post-increment in loops without any reason, so for-range loops are welcomed since they (should) use only the pre-increment. Oh yes, you also type less, and they fits well with STL containers.

The auto type is also lovely when you are assigning the vale from a C++ cast (especially if the cast is applied to a byte array). Since I tend to use verbose names, using auto removes me a lot of typing, especially when I need to refactoring. It is also sweet in templates °_° Edited by Alessio1989
1

Share this post


Link to post
Share on other sites

You can do that with the range-based loop too.

for(auto pValue : vValues)
{
	if(some_test(pValue))
		pValue->DoSomething)
}
Loop-modification is really the only perfect reason where range-based loops totally don't work.


Here's another one:
for (size_t i = 0, end = vValues.size(); i != end; ++i) {
  if (i > 0)
    std::cout << ", ";
  std::cout << *vValues[i];
}
std::cout << '\n';
2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0