last day (15 days later) » 

2:49 PM
Welcome! I'm glad you joined
I think this solution would be better: a class that would be templated by the number of std::string elements it holds, and a specialization for 0, where the buffer will be dynamic. What do you think about it?
 
I'm not sure if I understand. What advantages does it have over a class inherited from std::string with implicit conversion added?
 
it will not have undefined behavior :) inheriting from standard library containers is UB. Even though the inheriter doesn't have any data members added on top of the base class
 
"inheriting from standard library containers is UB" - Huh?
I'll check the standard I guess.
Btw, I know at least one case when it's not UB.
 
the child being empty?
 
Nah, I mean you can inherit from std::deque if remember correctly. The standard even mandates some of the field names to be not uglified.
 
2:57 PM
may be this post would be useful?
 
Ohhh.
So you're saying it's UB not because it's really UB, but because you can easily destruct it with incorrect destructor?
 
yeah, the problem is non virtual destructor of the standard containers
the memory layout is implementation dependent, so even if there is no members it might keep some bookkeeping stuff.
woops, it is not. It keeps them in order of declaration and some padding if needed. link. I know the answerer, he is quite cool xD
so, I think you can try to use it and hope that it won't break one day ;)
 
Hmm. That still sounds dangerous.
A simple void f(const std::string &) may break it.
 
not sure if I got the last message
 
Oh, sorry.
I mean if I construct temporary derived object in place with a call like f(MyString("")), then it will be bound to const reference and will be destructed with an improper destructor.
If I'm not mistaken.
 
3:10 PM
oh, yeah! that's the problem of const ref
should we update our goals? 1. We need to stream objects. 2. We need to retrieve the data, flush the stream, and give the data to the caller. 3. We need to figure out when we should delete/override the buffer. Am I right?
 
I think so. I'd prefer to keed the syntax but make it more resistant to incorrect usage.
I guess I can create a class with a single std::string field and implicit conversions to std::string and char *. Maybe also an overloaded -> to access std::string members. And return that instead.
 
the latter conversion is dangerous on reallocation
e.g. every concat can make the data dangling
 
You mean someone may try to realloc() or free() the pointer?
 
not only that, if string itself reallocates it's buffer, all the pointers get invalidated
 
Oh, that.
Also I wouldn't be able to save returned value in const char *...
I forgot, in which standard we're getting std::string_view?
 
3:18 PM
C++17
 
Oh.
Sorry, I got to go now. I will return in a two or three hours.
 
ok, bye
 
3:33 PM
I got a free moment to tell you a new idea I got.
I think I'll still use static buffers, but I will return a proxy object with a pointer to one of those buffers and add implicit conversions to char * and std::string &&.
 
so when proxy dies it will free the memory?
 
Nope, the memory will be in the buffer still.
Sorry, it got to got for real now. Sorry for weird timing.
 
 
3 hours later…
6:36 PM
Back!
@OlzhasZhumabek
 
sooo, did you implement it? I believe you can post it as answer and explain why it is better. I would like to have a look at that !
 
I was away, but I'll try to do it now.
Or maybe I should edit it into my post and wait for more feedback?
 
you can't change the code after an answer was posted
I'm not sure for now, but I believe that someone will come up with something better
 
@OlzhasZhumabek Oh, it's one of the rules?
 
@HolyBlackCat, yeah. It invalidates the previous reviews, so you can't edit an answer.
 
6:44 PM
Huh, thanks for telling me about that. I'd probably edit otherwise.
 
seems like you will need to post another question then
 
I think I'll post my answer and wait for feedback in comments.
At least for now.
 
nice idea too, I'll have a look at it tomorrow, I'm too tired for today
 
6:59 PM
So you're already going to go?
I have a problem with the implementation and thought that maybe you could help, but if you want to sleep, then do. :)
 
not really. I'm just relaxing. BTW I know russian if you're more comfortable with it
I can, I believe you can post code here or on ideone
 
Oh. It's not really important for me which language ro use.
I'll post that in a moment.
I currently have this.
 
the problem?
btw it should convert by itself, no need to typecast
when lhs is string
 
I thought it could be ambiguous.
Because string can be added to char * too.
Basically, the problem is that the call to std::string::operator=() is ambiguous when I try to assign JoProxyString to a string.
And I can't overload the = for std::string because it must be defined inside of the std::string itself.
 
let me have a closer look
 
7:05 PM
Ok. Try to do std::string something = Jo("hello"); and you'll see it.
 
can I start rewriting it? I have some places where it could be improved
 
Of course.
 
but yeah, lets solve the problem first
 
Yeah.
The original idea was that std::string ctors and assignment operators would prefer std::string && thus moving the string efficiently. But it turns that those ctors and assignments are ambiguous.
 
I think we could simplify expansion there. I'll ping you when I'll fix it
 
7:15 PM
You mean that use of std::initializer_list?
 
yes. It is really minor thing. Nevermind
 
Ok.
I start to think that it's impossible. If I have both casts, then std::string ctors and ='s calls are ambiguous. If I have only char * cast. then I get copies instead of moves (as before). std::string && will allow me to move, but it will prevent me from assigning the result to char *, which is very bad.
 
yeah, in my opinion there is a much better design to solve this
as you see code gets clumpy. You should try to implement a buffer class instead, probably circular buffer or queue is a good choice for this
btw standard library already has a queue implemented
 
It would make the interface more bulky.
 
both of them is just simplification of what you do. You just use standard library container instead of handling it on your own
I'll post a code in a minute
 
7:30 PM
Ok.
 
your Jo_ function will be like this
template <typename ...P> const char *Jo_(P &&... p)
{
	static queue_wrapper buffer;

	Internal::ss.clear();
	Internal::ss.str("");

	using expander = int[];
	(void)expander {(internal::ss << p, 0) ...};

	buffer.push(ss.str());
	const char* ret = buffer.back().c_str();
	return ret;
}
btw the queue_wrapper looks like this
class queue_wrapper
{
	std::queue<std::string> q;
public:
	void push(const std::string& s)
	{
		if (q.size() == 32)
			q.pop();

		q.emplace(s);
	}

	void push(std::string&& s)
	{
		if (q.size() == 32)
			q.pop();

		q.emplace(s);
	}

	const std::string& back()
	{
		return q.back();
	}
};
I think the problem is not so significant, so it would be better to work on something more significant. Nothing can be done to predict when the pointer should be freed
 
So basically it's just an internal structure change?
Hmm.
 
7:45 PM
yes, it makes it more bulletproof, although it can't resist an atom bomb yet
 
Uh, sorry, maybe I'm too sleppy and don't see something, but doesn't it produce same result as the old version?
The difference is that it's going to use dynamic allocation instead of static storage.
 
should it produce something else? It's just making the code prettier and stable. Everyone knows what queue is, but not everyone will immediately understand what you are trying to achieve by your code
 
you need to change your specifications to get something tangible. Anyway, the idea doesn't worth the headache.
I recommend you to move to something more interesting
 
Huh, you're right.
I think I have an idea and I'm going to try it, but then I'm done.
 
7:52 PM
ok, good luck
 
8:12 PM
Uh, I don't want to mess with that anymore. Any decent improvements to it would take too many time and wont worth it.
Going to do something *interesting* now, like learning how to do proper vector graphics over OpenGL using something like NanoVG.
Thanks for help.
 

last day (15 days later) »