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

Author Topic: I cannot access private member declared in sf::NonCopyable  (Read 3712 times)

0 Members and 1 Guest are viewing this topic.

magneonx

  • Full Member
  • ***
  • Posts: 141
    • MSN Messenger - magnumneon04@hotmail.com
    • View Profile
hello, so I am actually making an asset manager, I know there are tools for these but I prefer my own implementations because I have my own specific requirements. So my Asset class has just one requirement, that is it needs to have the implementation details on way on how to load that particular asset. Just think of C#'s Func<T,R> and Action<T>. That is what I am trying to do. Because instead of inheriting from a class just to have your own load implementation is quite cumbersome. I just want to enforce that loading scheme must be on the application level.

Here is my actual implementation:

#ifndef ASSET_HPP
#define ASSET_HPP

#include<map>
using std::map;
using std::pair;

#include<functional>
using std::function;

#include<string>
using std::string;

#include<memory>
using std::unique_ptr;

namespace esc
{
        template<class T>
        class Asset
        {

                typedef map<string, unique_ptr<T>> AssetLibrary;
                typedef function<T*(const string &)> LoadMethod;

                public:

                        Asset();
                        explicit Asset(const LoadMethod &);
                        virtual ~Asset();

                        bool loadFromFile(const string & oname, const string & path);
                        bool deleteFromAssetLibrary(const string &aname);

                        size_t getSize() const;
                        T * getAsset(const string &);

                private:

                        AssetLibrary library;
                        LoadMethod loadMethod;
        };

        template<class T> Asset<T>::Asset(){}

        template<class T>
        Asset<T>::Asset(const LoadMethod &_m)
                : loadMethod(_m)
        {

        }

        template<class T>
        Asset<T>::~Asset()
        {
       
        }

        template<class T>
        bool Asset<T>::loadFromFile(const string &oname, const string &path)
        {
                if(T * asset = loadMethod(path))
                {
                        library.insert(pair<string, unique_ptr<T>>(oname, unique_ptr<T>(asset)));
                        return true;
                }

                return false;
        }

        template<class T>
        bool Asset<T>::deleteFromAssetLibrary(const string &oname)
        {
                if (library.find(oname) == library.end())
                {
                        library.erase(oname);
                        return false;
                }

                return true;
        }

        template<class T>
        size_t Asset<T>::getSize() const
        {
                return library.size();
        }

        template<class T>
        T * Asset<T>::getAsset(const string &oname)
        {
                if (library.find(oname) == library.end())
                        return library[oname];

                return false;
        }
}

#endif
 

This the Asset<T> class, where T is the type of the asset. It requires on how to load that T regardless of what library I am using.

The following code is the implementation details on GameApplication, game application has the function to load the asset.

#include<iostream>
using std::cout;
using std::endl;

#include "GameApplication.hpp"
...

sf::Texture * GameApplication::loadTextureFromFile(const string & path)
{
        cout << "Calling this function..." << endl;

        sf::Texture * t = new sf::Texture();
       
        if (!t->loadFromFile(path))
                return nullptr;

        return t;
}
...
 

So here's how I "tested" it.

...
        GameApplication app;
        app.setScreenSize(800, 600);

        esc::Asset<sf::Texture> asset(bind(app, &GameApplication::loadTextureFromFile, _1));
       
        if (!asset.loadFromFile("object1", "URL"))
        {
                cout << "ERROR: file not found" << endl;
        }

        //return app.run();
...
 

This code works, well at least in compiling those source codes, but I hit a wall. SFML says that I cannot access  private member declared in sf::NonCopyable but doesn't tell which member.

I might have overlooked something. Did I miss something?

PS. Also, don't lecture me yet on wrong designs this and that, that is 8) not what I actually came here for. I hope you understand. We'll talk about that on my next post.

I just wanna learn std::function so this more of like for learning purposes and this one really bothers me. Thank you any help there is.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10901
    • View Profile
    • development blog
    • Email
Re: I cannot access private member declared in sf::NonCopyable
« Reply #1 on: May 07, 2014, 03:04:09 pm »
The error means that you're trying to make a copy of a class that derives of sf::NonCopyable, which as the name suggests, makes the class non copyable. I don't see anything in that direction in your code or have overlooked it.
Anyways you should post a minimal and complete example. If you start with the current code base a step by step disable things, you most likely will figure out on your own what went wrong.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

magneonx

  • Full Member
  • ***
  • Posts: 141
    • MSN Messenger - magnumneon04@hotmail.com
    • View Profile
Re: I cannot access private member declared in sf::NonCopyable
« Reply #2 on: May 07, 2014, 03:06:50 pm »
@eXpl0it3r as, always, thanks alot. I really cringe when this happens to me, its really hard to pin the error down. I'll try to deduce the code and see what happens.


eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10901
    • View Profile
    • development blog
    • Email
Re: I cannot access private member declared in sf::NonCopyable
« Reply #3 on: May 07, 2014, 03:10:38 pm »
Well as a first analysis you can just check which classes that you use with SFML are derived from sf::NonCopyable and then look at them and search for where a potential copy could be happening.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

magneonx

  • Full Member
  • ***
  • Posts: 141
    • MSN Messenger - magnumneon04@hotmail.com
    • View Profile
Re: I cannot access private member declared in sf::NonCopyable
« Reply #4 on: May 07, 2014, 03:17:07 pm »
Actually, its sf::Window, sf::RenderTarget that has this error, the compiler points to those two files and never tells which member.

Actually I have GameApplication class and declared a:

sf::RenderWindow window;
 

on the private scope, then invoke window creation when GameApplication start.

Maybe this causes the problem.. I just make a mock project and type each class piece by piece. As I have always done this and able to find the problem. I'll get back to this post shortly...

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10901
    • View Profile
    • development blog
    • Email
Re: I cannot access private member declared in sf::NonCopyable
« Reply #5 on: May 07, 2014, 03:22:54 pm »
There are only two private members in the class sf::NonCopyable, the copy constructor and the assignment operator. I bet your compiler tells you more, but you marked it off as "gibberish". ;D

Anyways just check where you're making a copy of your window or your game application.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: I cannot access private member declared in sf::NonCopyable
« Reply #6 on: May 07, 2014, 03:37:25 pm »
Here:

bind(app, ...);

Solution:

bind(std::ref(app), ...);
Laurent Gomila - SFML developer

magneonx

  • Full Member
  • ***
  • Posts: 141
    • MSN Messenger - magnumneon04@hotmail.com
    • View Profile
Re: I cannot access private member declared in sf::NonCopyable
« Reply #7 on: May 07, 2014, 03:57:50 pm »
Wow, geez. Thanks Laurent! Anyway, I got another error which is no longer related on this one. Thank you, now this is the time to improve the call site.

Maybe I misunderstood how bind actually works? It seems like its copying an instance of GameApplication? Though I get now how ref works on my code, but does it make another copy of GameApplication instance when you bind it to a function? I think I need more clarification.

magneonx

  • Full Member
  • ***
  • Posts: 141
    • MSN Messenger - magnumneon04@hotmail.com
    • View Profile
Re: I cannot access private member declared in sf::NonCopyable
« Reply #8 on: May 07, 2014, 04:06:04 pm »
it works now here is the solution:

esc::Asset<sf::Texture> asset(bind(&GameApplication::loadTextureFromFile, std::ref(app), _1));
 

Of course, the call site is ugly, which leads me to another problem, which I can solve or not. But big thanks guys!

magneonx

  • Full Member
  • ***
  • Posts: 141
    • MSN Messenger - magnumneon04@hotmail.com
    • View Profile
Re: I cannot access private member declared in sf::NonCopyable
« Reply #9 on: May 07, 2014, 04:09:18 pm »
Just a follow up, the previous code is totally wrong, since I have interchanged the value of the instance to binding function. The correct one should be, the instance then the function. I just have to clean my interface a bit. Thanks guys!

 

anything