Jump to content
  • Advertisement
Sign in to follow this  
3dmodelerguy

C++ A few questions about some c++ code

Recommended Posts

A few questions about some c++ code

So I am starting to get back into c++ after about 12 - 14 years away from it (and even back then, my level of knowledge was maybe a little above beginner) to do some game / SDL programming. I was following a tutorial to get at least a basic starting point for an entity component system and it works however there was some code that I don't quite understand even after looking around little.

First pice of code is:

T* component(new T(std::forward<TArguments>(arguments)...));

This seems to be assigning the `component` with the results of what is in the parentheses though normally I would expect this:

T* component = new T(std::forward<TArguments>(arguments)...);

Is this just syntax preference or does the compiler do something different with the parentheses (it is weird to me as when I see that, I think it is a function call)?

The second piece of code I think I understand the general idea of what it is doing but some of the specific are escaping me:

template <typename T, typename... TArguments>
T& Entity::addComponent(TArguments&&... arguments) {
  T* component = new T(std::forward<TArguments>(arguments)...);

So from my understanding, the first line would basically take this:

entity->addComponent<TransformComponent, int, int, int, int>(x, y, width, height);

and take of the first item in the template and assign the to T and then "group" (not sure the correct term) the rest of the items as a collection of some sort and then the `...` on the second line would group the arguments (that would need to match the template group) that were passed in. Then the third line is effectively converting the template / passed in arguments to be called like this:

TransformComponent* component = new TransformComponent(x, y, width, height);

The parts that are a bit confusing to me is first the `&&`. From what I have read (from stack overflow), that symbol means rvalue reference or reference to an argument that is about to be destroyed. Not quite sure what it means by it about to be destroyed.

The second part, which I think related to using `&&`, is the `std::forward<TArguments>`. The explainations that I have found so far as are bit confusing to me.

I will continue to try to find the answer to these confusions but I though maybe someone here might have an explanation that might make more sense to me. I would also consider it quite possible that there is some prerequisite knowledge that I might not have (I mean I think I have a decent understanding of pointers and references) so if there is other stuff I should looking into, that would be great too.

Share this post


Link to post
Share on other sites
Advertisement
Posted (edited)

The first code looks like a copy constructor call (or a 'move' call??), which is not the same as an assignment (operator=()).

The '&&' is the 'move' operation, the data is not copied, as with assignment, it is moved from the old to the new spot. It's needed for std::unique_ptr<>, and replaces the hacky 'auto_ptr' (I think it was called?). There are also a few other useful spots for it.

I have no idea what std::forward<> is doing, but en.cppreference.com should know.

 

You may want to grab a book about C++, and read it. A lot has changed, and is still being changed. It's like a totally new language.

Anything before c++11 isn't worth reading, but there is also c++14 and c++17, so you may want to find something newer than c++11.

Edited by Alberth

Share this post


Link to post
Share on other sites
Posted (edited)
On 5/15/2018 at 12:43 AM, 3dmodelerguy said:

This seems to be assigning the `component` with the results of what is in the parentheses though normally I would expect this

It invokes the constructor of T* with the result of the call 'new T([...])'. Given that this is a pointer, the arguments of the constructor for it are either none (the pointer is uninitialized) or simply the address of a variable. 

On 5/15/2018 at 12:43 AM, 3dmodelerguy said:

Is this just syntax preference or does the compiler do something different with the parentheses (it is weird to me as when I see that, I think it is a function call)?

No, it makes no difference in this context. Both will invoke the constructor with the matching arguments. That might not be too intuitive, given that it will call the assignment operator when the variable was already declared. Take this example:

class Vector
{
public:
    Vector() = default;
    
    Vector(const Vector& inOther)
    {
        std::cout << "Copying from other vector...";   
    }
    
    Vector& operator=(const Vector& inOther)
    {
        std::cout << "Clearing and then copying from the other vector...";
        return *this;
    }
};

int main()
{
    Vector vector;
    Vector vector2 = vector;
    vector2 = vector;
}

Which will print "Copying from other vector..." and then "Clearing and then copying from other vector...". 

 

On 5/15/2018 at 12:43 AM, 3dmodelerguy said:

new T(std::forward<TArguments>(arguments)...)

This part is more interesting. What it does is it forwards the arguments passed the function from which this is invoked, to T. Now @Alberth mentioned this invokes the copy or move constructor, but that's not necessarily the case. The function will likely look like this:

template<typename T, typename... TArguments>
void CreateComponent(TArguments... inArguments)
{
	T* component(new T(std::forward<TArguments>(inArguments)...));
}

This means you can pass an arbitrary amount of template arguments to CreateComponent and these are then forwarded to the constructor of type T. This could mean a copy/move constructor is invoked, if inArguments consists of just one instance of type T or whatever else there are copy/move constructors for, but it can also be any other constructor depending on inArguments.

The '...' in the template<[...], typename...[...]> means it is a parameter pack, which you can unpack by calling '...' on it again. This means the pack of 'TArguments' is expanded (unpacked) into the arguments for this function. Then, for each argument, we unpack the call to std::forward and thus forward each individual argument to it. That means each argument is forwarded from inArguments to the constructor. All std forward does is make sure that if any argument is of some reference type, it will keep being a reference once passed to the constructor of T.

On 5/15/2018 at 12:43 AM, 3dmodelerguy said:

 


template <typename T, typename... TArguments>
T& Entity::addComponent(TArguments&&... arguments) {
  T* component = new T(std::forward<TArguments>(arguments)...);

 

The && here means it's a universal reference, which is like this whole area of move semantics that makes it more confusing. What it basically means is that if I pass a reference value into this, it will retain its reference. That could either be a right-hand-value, or a left-hand-value. Both would retain their properties. This only applies to template arguments. If arguments weren't of a template type such as TArguments, this would be an rvalue-reference: a reference to a right-hand value (like again for example, the result of a function call) and would be used to distinguish between right-hand values and left-hand-values.

On 5/15/2018 at 12:43 AM, 3dmodelerguy said:

So from my understanding, the first line would basically take this:


entity->addComponent<TransformComponent, int, int, int, int>(x

You can generally omit the template arguments other than TransformComponent. The compiler should be able to infer this for you. 

On 5/15/2018 at 12:43 AM, 3dmodelerguy said:

Then the third line is effectively converting the template / passed in arguments to be called like this:


TransformComponent* component = new TransformComponent(x, y, width, height);



This is indeed what it will end up doing.

I agree on Alberth's advise, there's been quite a bit of change. Welcome to C++11 ;)

Edited by AthosVG

Share this post


Link to post
Share on other sites

@AthosVG

Thanks for provide a really nice detailed explanation, it did help clear up some confusion I had

@Alberth

Would you have any good books that you would recommended (ideally something updated to c++17)? I would ideally like a book that skips that very basic of programming that is common to most language (like variables, control flow, function basics, etc) and really focuses on the unique C++ stuff and more advance C++ topics.

Share this post


Link to post
Share on other sites
9 hours ago, 3dmodelerguy said:

Would you have any good books that you would recommended (ideally something updated to c++17)? I would ideally like a book that skips that very basic of programming that is common to most language (like variables, control flow, function basics, etc) and really focuses on the unique C++ stuff and more advance C++ topics.

Effective C++ by Scott Meyers pretty a must-have in that case. It skips pretty much all the basics and has updated revisions tailored around the newest standards (11, 14 and 17)

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  

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!