Roy
Is that bad that the counter will be increased?
No, just i like design when use increase counter when it's need
Pavel
Have task: return shared_ptr from function by reference if object exist or return empty shared_ptr, how i can do it? Important! I can return shared_ptr by value, but it's increase counter in shared_ptr if object exist. Has method for return by reference or value but without increase counter?
As for the task you can create e.g. a local static shared ptr and return it's reference when the object does not exist. But the problem is, because it's a reference someone can assign something to it and it will stop working properly
Alex
No, just i like design when use increase counter when it's need
you can`t control counter of shared_ptr, this is potential memory leak, or invalid memory access
Roy
If you creating shared_ptr in the method that returns it you must return by value anyway
yea, i know it, i mean, i need return shared_ptr object by reference if is not empty or by value if you return empty shared_ptr
Roy
Example, i have unordered_map where i storage shared_ptr in value, i'm try find key, if key not found i need return shared_ptr<> ()
Igor🇺🇦
yea, i know it, i mean, i need return shared_ptr object by reference if is not empty or by value if you return empty shared_ptr
If shared_ptr is empty is will be null and there won't be any counter. If you don't want counters use unique_ptr
Pavel
Example, i have unordered_map where i storage shared_ptr in value, i'm try find key, if key not found i need return shared_ptr<> ()
What if you return a shared ptr, someone will store the reference to it that you've returned and then unordered_map will reallocate the table (e.g. after an insert)
Roy
If I'm sure that I need a read-only object at the moment, then I don't need to increase the counter and waste performance
Pavel
It can happen even during the callstack when it returned (ok, not exactly like this)
Roy
this is a specific task: return an object by reference if it exists, or create an empty shared_ptr and return it so that the user can check if it is empty
Roy
return optional<shared_ptr>
no no it's bad idea
Igor🇺🇦
i need trick in my situation
why are you using shared_ptr if you only have a single owner?
Roy
i can use pointer in this situation, but i like reference design
Roy
why are you using shared_ptr if you only have a single owner?
So that users can create a copy of this object and store it in their class. This will prevent the need to call unordered_map.find
Roy
so you can use shared_ptr in your classes and if you reload your resources you not lost your data
Igor🇺🇦
Roy
if users store shared_ptr counter must be increased. That's kinda the point
yea, but if you return shared_ptr by reference, user can take your shared_ptr by value
Roy
example auto object = storage.get<type>(); // get method return shared_ptr by ref
Roy
Or (s)he can take it by reference and null it
what you say is beyond the bounds of idiocy on the part of the user. it might as well just call std::terminate
Roy
i mean user know what doit .reset method in shared_ptr or if you take it by reference and set new value
Roy
sorry my english in low level
Igor🇺🇦
yea, but if you return shared_ptr by reference, user can take your shared_ptr by value
If you store shared_ptr internally you van always return reference and have an empty share_ptr as const static
Roy
hmm, wait, i have idea, maybe create method Has and return iterator on object from this method?
Roy
and use context if(const auto it = HasResource<Type>(); it) { auto& resource = GetResource<Type>(it); }
Roy
just i'm stuck in ass situation
Roy
Wait i'm upload my code on pastebin
Igor🇺🇦
always
But you said that in some situations you want to return reference and in some value. You can't have both because it the same method signature from C++ perspective
Igor🇺🇦
and anyway - if an atomic increment is such a significant performance penalty return raw pointers.
Roy
Yes, the point is that I envisioned a design that is based only on references. The Has method is used to check the validity of objects, however, this calls the .find method in the map. Here example if(HasResource(key)) { auto& resource = GetResource(key); } The problem is that the class that stores the resources is based on unordered_map. HasResource method calls .find, and GetResource uses .find It turns out two calls to .find, which is a waste of performance.
Roy
So? Does GetResouce return shared_ptr?
Yea by reference now, but it's call .find twice, first in HasResource method, second in GetResource
Roy
Is it a likely situation that there's no resource found?
Yea, if your code is bad or you remove resources and want use it
Igor🇺🇦
Yea by reference now, but it's call .find twice, first in HasResource method, second in GetResource
Why are you calling hasResorce at all? You can check if (!share_ptr) -> object doesn't exist by caller
Igor🇺🇦
Why does it matter? Use reference if you wish show
Roy
or it's bad practice return shared_ptr by reference from objects pool
Igor🇺🇦
or it's bad practice return shared_ptr by reference from objects pool
I'm sorry, but I don't understand. Just return reference always. When do you need to return value?
Pavel
Yea, if your code is bad or you remove resources and want use it
I think you can make 2 functions: One returns a raw pointer (nullptr if nothing found), the second is returning shared_ptr by value (shared_ptr<T>() if nothing found). First one should be used if you don't want to store a pointer to the resource, the second if you want to store a pointer to it. The first function gives the minimal overhead. The second one gives overhead only in the case when the object was found but the caller still decided that (s)he doesn't want to store it.
Alex
or it's bad practice return shared_ptr by reference from objects pool
if you wish to deal with reference, you don`t need shared_ptr at all
Roy
I'm sorry, but I don't understand. Just return reference always. When do you need to return value?
You not return value, you return by reference, but user can take it by value
Roy
if you wish to deal with reference, you don`t need shared_ptr at all
No, i need it for realod resources without problems
Roy
Example, you load file config.json in memory and add all resources in class, after you want reload this file resources again, you extrace shared_ptr from storage class and try reload files, if reload config file failed you can push your extracted shared_ptr again in class
Igor🇺🇦
You not return value, you return by reference, but user can take it by value
Yes, always return reference. You said it yourself - you want user to be able to store it. So what's the problem? Always return by reference if users don't want to store it they will accept it by reference too.
Roy
Yes, always return reference. You said it yourself - you want user to be able to store it. So what's the problem? Always return by reference if users don't want to store it they will accept it by reference too.
you mean this? std::shared_ptr<std::string> foo() { static auto value = std::make_shared<std::string>(); return value; } void main() { auto& object = foo(); }
Igor🇺🇦
you mean this? std::shared_ptr<std::string> foo() { static auto value = std::make_shared<std::string>(); return value; } void main() { auto& object = foo(); }
std::shared_ptr<std::string>& foo() { static auto value = std::make_shared<std::string>(); return value; } void main() { auto& object = foo(); }
Pavel
Ah, wait, auto, nevermind
Roy
but how check has object or not? what is in map not exist your resource?
Roy
You can even skip the assignment of the static variable, it's empty by default.
No, no, it's example, static only for example, in my class it's unordered_map
Roy
Ok, wait, let me put my code on pastebin
Igor🇺🇦
This is what I'm doing now
std::shared_ptr<std::string>& foo() { static auto value = std::make_shared<std::string>(); return value; } void main() { auto& object = foo(); if (!object) return; }
Roy
i mean, your counter in shared_ptr increased, test it
Pavel
Or it's intended without it?
Igor🇺🇦
and you both forgot the & in the return value?
It should be a reference, it's just copy/paste works weirdly
Roy
and you both forgot the & in the return value?
No, you not understand, i need check exist resource or not and after get resource. But for check exist resource or not you need call unordered_map.find method and if your resource exist you need call get resource method, but he to call .find method, so it's call .find twice
Igor🇺🇦
Roy
https://pastebin.com/vmwvNEkR
Ricardo
Sorry. Please i have a problen with my menu program. I had to do three class ( personal, employer and compte) and let choose by the user any class he want to open and modify it.
Roy
Example usage struct Item {}; auto& storage = ResourceManager::CreateStorage<Item>(); storage.AddResource(100); storage.AddResource(200); if(storage.HasResource(100)) { auto& resource = storage.GetResource(100); }
Roy
Soo what problem? Problem in HasResource and GetResource, call .find method twice in unordered_map, it's small overhead but if you iterate in big storage it's not small overhead
Roy
Example, if you have storage where you have 1m resources, you call .find 2m times
Roy
Again - why do you need to call HasResource? your resource is shared_ptr. It knows if it's valid
ok, you call GetResource(key), but in unordered_map not has your resource, what next?