• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Ty Typhoon
      Before read everything i am honest:
      Payment after release you get your percentage lifetime for that project.
       
      Second:
      i dont need your inspirations, ideas, music or designs.
      My head is full with that.
      I need workers who i can trust.
       
       
       
      Please let us talk in discord.
      I got a lot of stuff planned, there is much work to do.
       
      But first my team and me try to start with a small mini game and we need maybe exactly you.
      Planned for more than pc, like ps4, xbox one and mobile - so its very important to us to hopefully welcome a programmer.
       
      The mini game will be part of the planned big game. There will be never before seen guns and gameplay, you will get deeper info if youre a safe part of the team.
       
      I need:
      Programmers
      Animators
      Zbrush pros
       
      Join here please:
      https://discord.gg/YtjE3sV
       
      You find me here:
      Joerg Federmann Composing#2898
       
       
    • By tj8146
      I am using immediate mode for OpenGL and I am creating a 2D top down car game. I am trying to configure my game loop in order to get my car-like physics working on a square shape. I have working code but it is not doing as I want it to. I am not sure as to whether it is my game loop that is incorrect or my code for the square is incorrect, or maybe both! Could someone help because I have been trying to work this out for over a day now
      I have attached my .cpp file if you wish to run it for yourself.. 
      WinMain code:
      /******************* WIN32 FUNCTIONS ***************************/ int WINAPI WinMain( HINSTANCE hInstance, // Instance HINSTANCE hPrevInstance, // Previous Instance LPSTR lpCmdLine, // Command Line Parameters int nCmdShow) // Window Show State { MSG msg; // Windows Message Structure bool done=false; // Bool Variable To Exit Loop Car car; car.x = 220; car.y = 140; car.dx = 0; car.dy = 0; car.ang = 0; AllocConsole(); FILE *stream; freopen_s(&stream, "CONOUT$", "w", stdout); // Create Our OpenGL Window if (!CreateGLWindow("OpenGL Win32 Example",screenWidth,screenHeight)) { return 0; // Quit If Window Was Not Created } while(!done) // Loop That Runs While done=FALSE { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? { if (msg.message==WM_QUIT) // Have We Received A Quit Message? { done=true; // If So done=TRUE break; } else // If Not, Deal With Window Messages { TranslateMessage(&msg); // Translate The Message DispatchMessage(&msg); // Dispatch The Message } } else // If There Are No Messages { if(keys[VK_ESCAPE]) done = true; void processKeys(Car& car); //process keyboard while (game_is_running) { loops = 0; while (GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) { update(car); // update variables next_game_tick += SKIP_TICKS; loops++; } display(car); // Draw The Scene SwapBuffers(hDC); // Swap Buffers (Double Buffering) } } } // Shutdown KillGLWindow(); // Kill The Window return (int)(msg.wParam); // Exit The Program } //WIN32 Processes function - useful for responding to user inputs or other events. LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { switch (uMsg) // Check For Windows Messages { case WM_CLOSE: // Did We Receive A Close Message? { PostQuitMessage(0); // Send A Quit Message return 0; // Jump Back } break; case WM_SIZE: // Resize The OpenGL Window { reshape(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height return 0; // Jump Back } break; case WM_LBUTTONDOWN: { mouse_x = LOWORD(lParam); mouse_y = screenHeight - HIWORD(lParam); LeftPressed = true; } break; case WM_LBUTTONUP: { LeftPressed = false; } break; case WM_MOUSEMOVE: { mouse_x = LOWORD(lParam); mouse_y = screenHeight - HIWORD(lParam); } break; case WM_KEYDOWN: // Is A Key Being Held Down? { keys[wParam] = true; // If So, Mark It As TRUE return 0; // Jump Back } break; case WM_KEYUP: // Has A Key Been Released? { keys[wParam] = false; // If So, Mark It As FALSE return 0; // Jump Back } break; } // Pass All Unhandled Messages To DefWindowProc return DefWindowProc(hWnd,uMsg,wParam,lParam); }  
      C++ and OpenGL code:
      int mouse_x=0, mouse_y=0; bool LeftPressed = false; int screenWidth=1080, screenHeight=960; bool keys[256]; float radiansFromDegrees(float deg) { return deg * (M_PI / 180.0f); } float degreesFromRadians(float rad) { return rad / (M_PI / 180.0f); } bool game_is_running = true; const int TICKS_PER_SECOND = 50; const int SKIP_TICKS = 1000 / TICKS_PER_SECOND; const int MAX_FRAMESKIP = 10; DWORD next_game_tick = GetTickCount(); int loops; typedef struct { float x, y; float dx, dy; float ang; }Car; //OPENGL FUNCTION PROTOTYPES void display(const Car& car); //called in winmain to draw everything to the screen void reshape(int width, int height); //called when the window is resized void init(); //called in winmain when the program starts. void processKeys(Car& car); //called in winmain to process keyboard input void update(Car& car); //called in winmain to update variables /************* START OF OPENGL FUNCTIONS ****************/ void display(const Car& car) { const float w = 50.0f; const float h = 50.0f; glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glTranslatef(100, 100, 0); glBegin(GL_POLYGON); glVertex2f(car.x, car.y); glVertex2f(car.x + w, car.y); glVertex2f(car.x + w, car.y + h); glVertex2f(car.x, car.y + h); glEnd(); glFlush(); } void reshape(int width, int height) // Resize the OpenGL window { screenWidth = width; screenHeight = height; // to ensure the mouse coordinates match // we will use these values to set the coordinate system glViewport(0, 0, width, height); // Reset the current viewport glMatrixMode(GL_PROJECTION); // select the projection matrix stack glLoadIdentity(); // reset the top of the projection matrix to an identity matrix gluOrtho2D(0, screenWidth, 0, screenHeight); // set the coordinate system for the window glMatrixMode(GL_MODELVIEW); // Select the modelview matrix stack glLoadIdentity(); // Reset the top of the modelview matrix to an identity matrix } void init() { glClearColor(1.0, 1.0, 0.0, 0.0); //sets the clear colour to yellow //glClear(GL_COLOR_BUFFER_BIT) in the display function //will clear the buffer to this colour. } void processKeys(Car& car) { if (keys[VK_UP]) { float cdx = sinf(radiansFromDegrees(car.ang)); float cdy = -cosf(radiansFromDegrees(car.ang)); car.dx += cdx; car.dy += cdy; } if (keys[VK_DOWN]) { float cdx = sinf(radiansFromDegrees(car.ang)); float cdy = -cosf(radiansFromDegrees(car.ang)); car.dx += -cdx; car.dy += -cdy; } if (keys[VK_LEFT]) { car.ang -= 2; } if (keys[VK_RIGHT]) { car.ang += 2; } } void update(Car& car) { car.x += car.dx*next_game_tick; }  
      game.cpp
    • By tj8146
      I am using immediate mode for OpenGL and I am creating a 2D top down car game. I am trying to configure my game loop in order to get my car-like physics working on a square shape. I have working code but it is not doing as I want it to. I am not sure as to whether it is my game loop that is incorrect or my code for the square is incorrect, or maybe both! Could someone help because I have been trying to work this out for over a day now
      I have attached my .cpp file if you wish to run it for yourself.. 
       
      This is my C++ and OpenGL code:
      int mouse_x=0, mouse_y=0; bool LeftPressed = false; int screenWidth=1080, screenHeight=960; bool keys[256]; float radiansFromDegrees(float deg) { return deg * (M_PI / 180.0f); } float degreesFromRadians(float rad) { return rad / (M_PI / 180.0f); } bool game_is_running = true; const int TICKS_PER_SECOND = 50; const int SKIP_TICKS = 1000 / TICKS_PER_SECOND; const int MAX_FRAMESKIP = 10; DWORD next_game_tick = GetTickCount(); int loops; typedef struct { float x, y; float dx, dy; float ang; }Car; //OPENGL FUNCTION PROTOTYPES void display(const Car& car); //called in winmain to draw everything to the screen void reshape(int width, int height); //called when the window is resized void init(); //called in winmain when the program starts. void processKeys(Car& car); //called in winmain to process keyboard input void update(Car& car); //called in winmain to update variables /************* START OF OPENGL FUNCTIONS ****************/ void display(const Car& car) { const float w = 50.0f; const float h = 50.0f; glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glTranslatef(100, 100, 0); glBegin(GL_POLYGON); glVertex2f(car.x, car.y); glVertex2f(car.x + w, car.y); glVertex2f(car.x + w, car.y + h); glVertex2f(car.x, car.y + h); glEnd(); glFlush(); } void reshape(int width, int height) // Resize the OpenGL window { screenWidth = width; screenHeight = height; // to ensure the mouse coordinates match // we will use these values to set the coordinate system glViewport(0, 0, width, height); // Reset the current viewport glMatrixMode(GL_PROJECTION); // select the projection matrix stack glLoadIdentity(); // reset the top of the projection matrix to an identity matrix gluOrtho2D(0, screenWidth, 0, screenHeight); // set the coordinate system for the window glMatrixMode(GL_MODELVIEW); // Select the modelview matrix stack glLoadIdentity(); // Reset the top of the modelview matrix to an identity matrix } void init() { glClearColor(1.0, 1.0, 0.0, 0.0); //sets the clear colour to yellow //glClear(GL_COLOR_BUFFER_BIT) in the display function //will clear the buffer to this colour. } void processKeys(Car& car) { if (keys[VK_UP]) { float cdx = sinf(radiansFromDegrees(car.ang)); float cdy = -cosf(radiansFromDegrees(car.ang)); car.dx += cdx; car.dy += cdy; } if (keys[VK_DOWN]) { float cdx = sinf(radiansFromDegrees(car.ang)); float cdy = -cosf(radiansFromDegrees(car.ang)); car.dx += -cdx; car.dy += -cdy; } if (keys[VK_LEFT]) { car.ang -= 2; } if (keys[VK_RIGHT]) { car.ang += 2; } } void update(Car& car) { car.x += car.dx*next_game_tick; } My WinMain code:
      /******************* WIN32 FUNCTIONS ***************************/ int WINAPI WinMain( HINSTANCE hInstance, // Instance HINSTANCE hPrevInstance, // Previous Instance LPSTR lpCmdLine, // Command Line Parameters int nCmdShow) // Window Show State { MSG msg; // Windows Message Structure bool done=false; // Bool Variable To Exit Loop Car car; car.x = 220; car.y = 140; car.dx = 0; car.dy = 0; car.ang = 0; AllocConsole(); FILE *stream; freopen_s(&stream, "CONOUT$", "w", stdout); // Create Our OpenGL Window if (!CreateGLWindow("OpenGL Win32 Example",screenWidth,screenHeight)) { return 0; // Quit If Window Was Not Created } while(!done) // Loop That Runs While done=FALSE { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? { if (msg.message==WM_QUIT) // Have We Received A Quit Message? { done=true; // If So done=TRUE break; } else // If Not, Deal With Window Messages { TranslateMessage(&msg); // Translate The Message DispatchMessage(&msg); // Dispatch The Message } } else // If There Are No Messages { if(keys[VK_ESCAPE]) done = true; void processKeys(Car& car); //process keyboard while (game_is_running) { loops = 0; while (GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) { update(car); // update variables next_game_tick += SKIP_TICKS; loops++; } display(car); // Draw The Scene SwapBuffers(hDC); // Swap Buffers (Double Buffering) } } } // Shutdown KillGLWindow(); // Kill The Window return (int)(msg.wParam); // Exit The Program } //WIN32 Processes function - useful for responding to user inputs or other events. LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information { switch (uMsg) // Check For Windows Messages { case WM_CLOSE: // Did We Receive A Close Message? { PostQuitMessage(0); // Send A Quit Message return 0; // Jump Back } break; case WM_SIZE: // Resize The OpenGL Window { reshape(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height return 0; // Jump Back } break; case WM_LBUTTONDOWN: { mouse_x = LOWORD(lParam); mouse_y = screenHeight - HIWORD(lParam); LeftPressed = true; } break; case WM_LBUTTONUP: { LeftPressed = false; } break; case WM_MOUSEMOVE: { mouse_x = LOWORD(lParam); mouse_y = screenHeight - HIWORD(lParam); } break; case WM_KEYDOWN: // Is A Key Being Held Down? { keys[wParam] = true; // If So, Mark It As TRUE return 0; // Jump Back } break; case WM_KEYUP: // Has A Key Been Released? { keys[wParam] = false; // If So, Mark It As FALSE return 0; // Jump Back } break; } // Pass All Unhandled Messages To DefWindowProc return DefWindowProc(hWnd,uMsg,wParam,lParam); }  
      game.cpp
    • By Ty Typhoon
      I like to build my A - Team now.
       
      I need loyal people who can trust and believe in a dream.
      If you got time and no need for direct pay please contact me now.
       
      We cant pay now, you will recieve a lifetime percentage if the released game will give earnings. 
      If I get the best people together for a team, everything should be possible.
       
       
      What i need:
      - Programmer c++
      - Unity / Unreal - we must check whats possible, please share your experience with me.
      - Sculpter, 3D Artist
      - Animator
      - Marketing / Promotion 
       
       
      What i do:
      - Studio Owner
      - Director
      - Recruit exactly you
      - Sounddesign
      - Main theme composing
      - Vocals
      - Game design
      - Gun, swords, shields and weapon design
      - Character, plants and animal design
       
       
      Please dont ask about the Name of the Game, about Designs or Screenshots.
      The game will be defintitly affected about our and your skills if you join the team.
       
       
      Planned for the big Game:
      - 1st person shooter
      - online multiplayer
      - character manipulation
      - complete big open world with like lifetime actions and reactions
      - gunstore with many items to buy
      - many upgrades for players
      - specials like mini games
       
      So if you are interested in joining a team with a nearly complete game idea, contact me now and tell me what you can do.
       
      discord:
      joerg federmann composing#2898
       
       
    • By codelyoko373
      I wasn't sure if this would be the right place for a topic like this so sorry if it isn't.
      I'm currently working on a project for Uni using FreeGLUT to make a simple solar system simulation. I've got to the point where I've implemented all the planets and have used a Scene Graph to link them all together. The issue I'm having with now though is basically the planets and moons orbit correctly at their own orbit speeds.
      I'm not really experienced with using matrices for stuff like this so It's likely why I can't figure out how exactly to get it working. This is where I'm applying the transformation matrices, as well as pushing and popping them. This is within the Render function that every planet including the sun and moons will have and run.
      if (tag != "Sun") { glRotatef(orbitAngle, orbitRotation.X, orbitRotation.Y, orbitRotation.Z); } glPushMatrix(); glTranslatef(position.X, position.Y, position.Z); glRotatef(rotationAngle, rotation.X, rotation.Y, rotation.Z); glScalef(scale.X, scale.Y, scale.Z); glDrawElements(GL_TRIANGLES, mesh->indiceCount, GL_UNSIGNED_SHORT, mesh->indices); if (tag != "Sun") { glPopMatrix(); } The "If(tag != "Sun")" parts are my attempts are getting the planets to orbit correctly though it likely isn't the way I'm meant to be doing it. So I was wondering if someone would be able to help me? As I really don't have an idea on what I would do to get it working. Using the if statement is truthfully the closest I've got to it working but there are still weird effects like the planets orbiting faster then they should depending on the number of planets actually be updated/rendered.
  • Advertisement
  • Advertisement

Recommended Posts

I can't tell if I'm running into a  bug or just don't know how to write this.

Basically I have my own extended VECTOR class derived from std::vector, which is non-copiable. This is by design, because I want to enforce strict rules on when complex objects can be duplicated or how they can be stored. Hence every class that contains a VECTOR is by definition also non-copiable by default.

What I'm writing is an allocator proxy, which is used by the type library during abstract processes like deserialization - it takes a base pointer, casts it to a container type and does stuff with it. It can handle smart pointers and raw objects, but currently has no way of differentiating between the two. Which becomes a problem when a type is non-copiable. This is where things start getting weird.

In Visual Studio I can successfully use the allocator on some complex types (eg types with one or more vector members whose copy assignment and constructor are either not provided), which should not be possible (unless, I guess, VS performs some selective on-demand compilation even in debug mode). In other cases the test fails correctly and the code does not compile.

So I figured, okay - I can just modify the allocator to conditionally compile only the parts that do not handle raw non-copiable objects in containers. All I would have to do is use something like is_copy_constructible<> to  determine which parts get compiled. But no - ALL of the classes I tested this with return true - both classes that contain non-copiable members with no copy constructor defined as well as simple classes that should be trivially copiable. Conversely, is_trivially_copy_constructible<> returns false to ALL of the classes I tried. Okay, then - maybe I'm just too dumb. Besides, the compiler does tell me the offending function is the auto-generated copy assignment operator, not the constructor. So I tried is_copy_assignable<>...

Which doesn't compile:

Error    1    error C2280: 'VECTOR<IActor *> &VECTOR<IActor *>::operator =(const VECTOR<IActor *> &)' : attempting to reference a deleted function   

 

 

I'm confused - maybe I'm completely misinterpreting the docs, but how do I determine whether an object is copiable at compile time? Why does is_copy_assignable<> apparently generate the assignment operator, which then fails to compile? Isn't the entire point of type traits to determine whether a condition is true without altering the behavior of the code in the process? Is this a bug in VS2013, because cppreference.com clearly states: "checks if a type has a copy assignment operator"?

Most importantly - what is a possible solution here?

Share this post


Link to post
Share on other sites
Advertisement

Extending a standard library container class is almost always the wrong approach.  There are very few things in the standard library designed for extension, and those are clearly indicated.  It is possible to extend some of them, but it usually comes with unexpected ramifications.

Your desire to mix smart pointers and raw pointers, as well as trying to describe what can be copied all reek of a common problem.  Controlling the lifetime of objects is a critical aspect of software, especially true in games. What you describe sounds like a symptom of not understanding what code owns the lifetime.  What is the REAL problem you are trying to solve here? You came up with a solution of trying to do complex things with a vector, but what problem drove you to that solution?

Share this post


Link to post
Share on other sites
1 hour ago, frob said:

Extending a standard library container class is almost always the wrong approach.  There are very few things in the standard library designed for extension, and those are clearly indicated.  It is possible to extend some of them, but it usually comes with unexpected ramifications.

Your desire to mix smart pointers and raw pointers, as well as trying to describe what can be copied all reek of a common problem.  Controlling the lifetime of objects is a critical aspect of software, especially true in games. What you describe sounds like a symptom of not understanding what code owns the lifetime.  What is the REAL problem you are trying to solve here? You came up with a solution of trying to do complex things with a vector, but what problem drove you to that solution?

I'm doing three things in my overloaded vector class:

1) provide a couple of wrapper functions like quick_erase()
2) disable the copy constructor and copy assignment operator
3) provide a custom allocator

I don't see how any of these violate the extensibility of any standard library class.

I'm not mixing shared and raw pointers. Neither is this particular issue in any way related to controlling lifetimes, although fundamentally it does stem from it. The real problem is exactly the one I described in my post. Given (untested pseudocode):


struct NonCopiable {
	// disables copy semantics
	VECTOR<int32> data;
};
      
template<typename T, bool ISCOPIABLE>
class Allocator {
  public:
    // should always work
	void AllocPointer(void* basePtr)
    	{
      	VECTOR<shared_ptr<T>>* container = reinterpret_cast<VECTOR<shared_ptr<T>>*>(basePtr);
      
     	container->push_back(NewShared<T>());
		}
      
    // should not work with T = NonCopiable. I want to selectively compile this into a stub that throws,
    // indicating an error...
	template <boolean ISCOPIABLE2>
	typename std::enable_if < ISCOPIABLE2, void* >::type
	void DoAllocPlain(void* basePtr)
    	{
      	VECTOR<T>* container = reinterpret_cast<VECTOR<T>*>(basePtr);
      
     	container->push_back(T());
		}
    // ... which means that for T = NonCopiable it should become
	template <boolean ISCOPIABLE2>
	typename std::enable_if <!ISCOPIABLE2, void* >::type      
	void DoAllocPlain(void* basePtr)
    	{
      	throw("You done goofed");
		}  
      
     void AllocPlain() { DoAllocPlain<ISCOPIABLE>(basePtr); }
};
      
...

void LoadToContainer(void *basePtr, int32 contType)
{
      
      
     Allocator<NonCopiable, std::is_copy_assignable<NonCopiable>> allocator;
     ...
     if(contType == ContainerOfSharedPointers)
      	allocator->AllocPointer(basePtr);
     else
      	allocator->AllocPlain(basePtr);
}

It would make no difference if I was using std::vector directly and passing it a plain non-copiable type. It wouldn't compile, resulting in the same situation.

So, to reiterate - my question is about type traits and how to properly employ them to decide which version of AllocPlain() should be compiled.

Edit: added enable_if to the sample code and fixed a few mistakes. PS - code editing in the new forums is apparently exceptionally broken.

Edited by irreversible

Share this post


Link to post
Share on other sites

std::vector is resizable, which means it needs to be able to copy its data to a new location if it runs out of space, wouldn't it? Not sure how you can store non-copiable elements in it, my guess is not.

Resizability also means the actual vector data is not the container<> object, as far as I kcan see. If the actual vector data was in the container<> object, it could move if you add an element and it needs resizing, and the STL API doesn't say anything about that. Therefore, your allocation is perhaps not even allocating what you think you're allocating?

Instead of fighting the STL, why not make your own wrapper class around a new-ed T[] array? That would be much simpler to get working, I suspect.

Share this post


Link to post
Share on other sites
27 minutes ago, Alberth said:

std::vector is resizable, which means it needs to be able to copy its data to a new location if it runs out of space, wouldn't it? Not sure how you can store non-copiable elements in it, my guess is not.

Resizability also means the actual vector data is not the container<> object, as far as I kcan see. If the actual vector data was in the container<> object, it could move if you add an element and it needs resizing, and the STL API doesn't say anything about that. Therefore, your allocation is perhaps not even allocating what you think you're allocating?

Instead of fighting the STL, why not make your own wrapper class around a new-ed T[] array? That would be much simpler to get working, I suspect.

I'm just going to assume that I'm extremely poor at communicating my problem at this point :)

This is exactly the thing I'm trying to not to do. I want to automatically NOT generate code in a generic class that would handle non-copiables in a container, throwing instead if I accidentally I do end up trying to do so. 

I feel like a really bad communicator here. How could I further clarify my question?

Share this post


Link to post
Share on other sites
2 hours ago, Hodgman said:

A derived class can never renege on features provided by the base class; doing so is an violation of OO's LSP rule, so this approach is invalid. OO would force you to use composition instead of inheritance here. Make your own class from scratch which contains a vector within the private implementation details.

Fair enough - that makes sense. Thanks for the heads up, although I'm somewhat curious how this becomes invalid in practice so long as I use the derived class - the compiler doesn't seem to be bothered by it.

Also, that being said, why does the below code generate a deleted function compile time error for both is_copy_assignable and is_trivially_copy_assignable:

error C2280: 'myvec<int32> myvec<int32>::operator =(const myvec<int32> &)' : attempting to reference a deleted function  

is_trivially_copy_constructible yields false and is_copy_constructible yields true.

My expectation would be that all of these cases would a) compile and b) yield false on the account of my explicitly disabling the copy semantics. As mentioned above, I'm using VS2013.
 

template<typename T>
class myvec {
    private:
        std::vector<T> detail;

    public:
  		myvec() { }
  
        myvec<T> operator=(IN const myvec<T>& copy) = delete;
        myvec(IN const myvec<T>& copy) = delete;
};

  
class NonCopiableA {
        myvec<int32>	vec;
};

  
... (DOUTEX() is a debug output macro) ...
  
    DOUTEX(std::is_copy_assignable<NonCopiableA>::value);
    DOUTEX(std::is_trivially_copy_assignable<NonCopiableA>::value);
    DOUTEX(std::is_copy_constructible<NonCopiableA>::value);
    DOUTEX(std::is_trivially_copy_constructible<NonCopiableA>::value);

Share this post


Link to post
Share on other sites
5 minutes ago, irreversible said:

Also, that being said, why does the below code generate a deleted function compile time error for both is_copy_assignable and is_trivially_copy_assignable:

Nowadays, C++ compilers seem pretty much ok with having implementations only for code that you actually use. My g++ happily compiles plain classes that have unused method declarations without any implementation. In the past it would throw "invalid v-table" errors during linking.

My guess is that your test-case doesn't use all functionality, and only hits the error when you access a method that uses the deleted functionality.

Share this post


Link to post
Share on other sites
15 minutes ago, Alberth said:

Nowadays, C++ compilers seem pretty much ok with having implementations only for code that you actually use. My g++ happily compiles plain classes that have unused method declarations without any implementation. In the past it would throw "invalid v-table" errors during linking.

My guess is that your test-case doesn't use all functionality, and only hits the error when you access a method that uses the deleted functionality.

The problem is that in the above test case I don't see where the code would be used :). I'm not omitting anything.

Share this post


Link to post
Share on other sites
28 minutes ago, irreversible said:

I'm somewhat curious how this becomes invalid in practice so long as I use the derived class - the compiler doesn't seem to be bothered by it.

It's a violation of OO theory, not the OOP constructs of C++ in practice. OO theory says that any algorithm that works on a base class, must also work on all derived types. You can break these rules in theory, but that means that you can't really claim to be writing "OO" code, even though you're using OOP language features...

Another C++-specific solution would be to use private (implementation) inheritance, which sidesteps the theoretical rules that come with public (interface) inheritance, as implementation inheritance doesn't exist in the theory.

28 minutes ago, irreversible said:

Also, that being said, why does the below code generate a deleted function compile time error for both is_copy_assignable and is_trivially_copy_assignable:

That is confusing... however it doesn't happen for me on MSVC2015... Also I get:
std::is_copy_assignable<NonCopiableA>::value == false
std::is_trivially_copy_assignable<NonCopiableA>::value == false
std::is_copy_constructible<NonCopiableA>::value == false
std::is_trivially_copy_constructible<NonCopiableA>::value == false

Can you post a compilable example and note the line that causes the compile error?

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


  • Advertisement