Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

overloading static operator + (non member) with non-class native types ...

39 views
Skip to first unread message

Soviet_Mario

unread,
Sep 19, 2019, 6:22:44 PM9/19/19
to
Surely this will sound a very trivial or silly question to
experienced C++ programmers, but I have many doubts about
it, starting with the very fact it is feasible or not.

I'd like to overload binary operator '+' for native CHAR *
operands on both sides, and return an std::string for the
resulting expression (like a "const" append or chain +
operator).

I suspect it would be slow (with "a lot" of temporaries
built and destroied), assumed it's possible.

What other risks should I try to avoid ?

a code like

std::string operator + (const char * A, const char * B)
{ return (std::string (A) + std::string (B)); }

does not compile with QT creator (it says : must have a
class or enumerated type operand).
How to circumvent the limitation without again "wrapping"
another std::string around the char * ?

I'd have thought that the std::string return type required
could have been enough, but it had not :\


the aim would be to allow "mixed" multiple chain operation
in composing strings in a sequence, with at least one
STD::STRING somewhere in the sequence, but also one or more
simple native literals (CHAR *) consecutive in it.

What other "semantic" could be altered to allow such
smoother integration between the two types ?



in the message it mentions __Cx11. Is it the standard implied ?
TY.



--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)

Paavo Helde

unread,
Sep 20, 2019, 2:09:18 AM9/20/19
to
On 20.09.2019 1:22, Soviet_Mario wrote:
> Surely this will sound a very trivial or silly question to experienced
> C++ programmers, but I have many doubts about it, starting with the very
> fact it is feasible or not.
>
> I'd like to overload binary operator '+' for native CHAR * operands on
> both sides, and return an std::string for the resulting expression (like
> a "const" append or chain + operator).
>
> I suspect it would be slow (with "a lot" of temporaries built and
> destroied), assumed it's possible.
>
> What other risks should I try to avoid ?
>
> a code like
>
> std::string operator + (const char * A, const char * B)
> { return (std::string (A) + std::string (B)); }
>
> does not compile with QT creator (it says : must have a class or
> enumerated type operand).
> How to circumvent the limitation without again "wrapping" another
> std::string around the char * ?

You cannot overload operators on built-in types like raw pointers.
That's basically what the error message tells you.

>
> I'd have thought that the std::string return type required could have
> been enough, but it had not :\

Return value type is not used for overload deduction.

>
>
> the aim would be to allow "mixed" multiple chain operation in composing
> strings in a sequence, with at least one STD::STRING somewhere in the
> sequence, but also one or more simple native literals (CHAR *)
> consecutive in it.

This is currently working:

#include <string>
using namespace std::literals::string_literals;

std::string foo() {
return "full "s + "moon"s;
}

std::string bar(const char* a, const char* b) {
return ""s + a + b;
}

Bo Persson

unread,
Sep 20, 2019, 5:52:51 AM9/20/19
to
On 2019-09-20 at 00:22, Soviet_Mario wrote:
> Surely this will sound a very trivial or silly question to experienced
> C++ programmers, but I have many doubts about it, starting with the very
> fact it is feasible or not.
>
> I'd like to overload binary operator '+' for native CHAR * operands on
> both sides, and return an std::string for the resulting expression (like
> a "const" append or chain + operator).
>
> I suspect it would be slow (with "a lot" of temporaries built and
> destroied), assumed it's possible.
>
> What other risks should I try to avoid ?
>
> a code like
>
> std::string operator + (const char * A, const char * B)
> { return (std::string (A) + std::string (B)); }
>
> does not compile with QT creator (it says : must have a class or
> enumerated type operand).
> How to circumvent the limitation without again "wrapping" another
> std::string around the char * ?
>
> I'd have thought that the std::string return type required could have
> been enough, but it had not :\
>
>
> the aim would be to allow "mixed" multiple chain operation in composing
> strings in a sequence, with at least one STD::STRING somewhere in the
> sequence, but also one or more simple native literals (CHAR *)
> consecutive in it.
>

If the strings ARE literals, you don't even need the + to concatenate
them. Consecutive literals are combined by the preprocessor:

std::string s = "Hello" ", " "World!";



Soviet_Mario

unread,
Sep 20, 2019, 12:05:34 PM9/20/19
to
what's the meaning of that suffix 's' after the literal char
string ? I've never seen that modifier :\

>
> std::string bar(const char* a, const char* b) {
>     return ""s + a + b;
> }
>

I was trying to call functions via binary operator for
brevity and clearness of the notation.
Via function call synthax I would not have met the problems
mentioned.

I understand now there seem not to be a simple workaround,
alas :(

Soviet_Mario

unread,
Sep 20, 2019, 12:09:18 PM9/20/19
to
no, actually a mixture of std::string variables and some
literals, to build variable error messages.

I'd like a uniform notation when mixing this sort of data
... but not functional notation, rather heavy when chaining
a lot of small fragments.

I'm trying to avoid per-use of sprintf and asprintf ...
maybe I'll have to resort to them. The format string is
rather obscure, but later the comma notation of the variadic
list is very short and clear.

Keith Thompson

unread,
Sep 20, 2019, 2:31:38 PM9/20/19
to
Soviet_Mario <Sovie...@CCCP.MIR> writes:
[...]
> what's the meaning of that suffix 's' after the literal char
> string ? I've never seen that modifier :\

It was added in C++14.

https://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

Paavo Helde

unread,
Sep 20, 2019, 2:52:18 PM9/20/19
to
On 20.09.2019 19:05, Soviet_Mario wrote:
> what's the meaning of that suffix 's' after the literal char string ?
> I've never seen that modifier :\

I hoped that the line "using namespace std::literals::string_literals"
would give a hint or at least provide something to google. But
apparently not.

Anyway, "abc"s is a std::string literal. You know, these are the kind of
literals one should use in C++. The char* strings (and the problems with
concatenating them) belong to another language which is supported for
legacy only. If you just avoid using char* strings and literals your
problem will disappear.


Paavo Helde

unread,
Sep 20, 2019, 2:55:56 PM9/20/19
to
On 20.09.2019 19:09, Soviet_Mario wrote:
>
> no, actually a mixture of std::string variables and some literals, to
> build variable error messages.
>
> I'd like a uniform notation when mixing this sort of data ... but not
> functional notation, rather heavy when chaining a lot of small fragments.

I hope you are aware that you only need "functional notation" for the
first string in the chain.


Keith Thompson

unread,
Sep 20, 2019, 3:04:11 PM9/20/19
to
Paavo Helde <myfir...@osa.pri.ee> writes:
> On 20.09.2019 1:22, Soviet_Mario wrote:
[...]
>> the aim would be to allow "mixed" multiple chain operation in composing
>> strings in a sequence, with at least one STD::STRING somewhere in the
>> sequence, but also one or more simple native literals (CHAR *)
>> consecutive in it.
>
> This is currently working:
>
> #include <string>
> using namespace std::literals::string_literals;
>
> std::string foo() {
> return "full "s + "moon"s;
> }
>
> std::string bar(const char* a, const char* b) {
> return ""s + a + b;
> }

"..."s was added in C++14. If you can't rely on that, just
ensure that the *first* argument in the chain of "+" operators
is a std::string, not a C-style string or char*. As long as
the left operand of each "+" is a std::string, it should work.
There's (probably) no need to create a new overload.

This works in C++14 and later:
using namespace std::literals::string_literals;
// ...
std::cout << ""s + "hello" + ' ' + "world" + '\n';
In C++11 and later:
std::cout << std::string{} + "hello" + ' ' + "world" + '\n';
In C++98 and later:
std::cout << std::string() + "hello" + ' ' + "world" + '\n';
// OR
std::cout << std::string("") + "hello" + ' ' + "world" + '\n';

Soviet_Mario

unread,
Sep 21, 2019, 5:44:22 AM9/21/19
to
On 20/09/2019 20:52, Paavo Helde wrote:
> On 20.09.2019 19:05, Soviet_Mario wrote:
>> what's the meaning of that suffix 's' after the literal
>> char string ?
>> I've never seen that modifier :\
>
> I hoped that the line "using namespace
> std::literals::string_literals" would give a hint or at
> least provide something to google. But apparently not.

ah...okay, no did not even suspect such feature before

>
> Anyway, "abc"s is a std::string literal. You know, these are
> the kind of literals one should use in C++.

Good thing a native constant std::string !! I'll search
literals spread in code to replace with this new native type.

Uh another related question. When one uses a true string
literal "ABC"s to just intialize a variable string, instead
of a "ABC" char *, a more efficient code is generated ?

I mean, apart from the constness, these new literals are
identical types to std::string or


> The char*
> strings (and the problems with concatenating them) belong to
> another language which is supported for legacy only.

I understand this position, but thank God the back
compatibility is maintained. Quite some are still amidst the
transition and use C++ as just an improved C with classes

> If you
> just avoid using char* strings and literals your problem
> will disappear.

notice taken, I'll try to locate the more old style literals
I can to replace. And also the ugly .append () notation

Soviet_Mario

unread,
Sep 21, 2019, 5:50:20 AM9/21/19
to
On 20/09/2019 21:03, Keith Thompson wrote:
> Paavo Helde <myfir...@osa.pri.ee> writes:
>> On 20.09.2019 1:22, Soviet_Mario wrote:
> [...]
>>> the aim would be to allow "mixed" multiple chain operation in composing
>>> strings in a sequence, with at least one STD::STRING somewhere in the
>>> sequence, but also one or more simple native literals (CHAR *)
>>> consecutive in it.
>>
>> This is currently working:
>>
>> #include <string>
>> using namespace std::literals::string_literals;
>>
>> std::string foo() {
>> return "full "s + "moon"s;
>> }
>>
>> std::string bar(const char* a, const char* b) {
>> return ""s + a + b;
>> }
>
> "..."s was added in C++14.

oh, I see ... installed QT reports C++11 if I'm not wrong.
Dunno if free upgrades are available (i have the free version)

On the system the installed compiler versions are :

GCC 6.3.0-18 and GCC 4:6.3.0-4 (I don't think QT ships a
compiler of its own in the free version)


> If you can't rely on that, just
> ensure that the *first* argument in the chain of "+" operators
> is a std::string, not a C-style string or char*. As long as
> the left operand of each "+" is a std::string, it should work.
> There's (probably) no need to create a new overload.
>
> This works in C++14 and later:
> using namespace std::literals::string_literals;
> // ...
> std::cout << ""s + "hello" + ' ' + "world" + '\n';
> In C++11 and later:
> std::cout << std::string{} + "hello" + ' ' + "world" + '\n';
> In C++98 and later:
> std::cout << std::string() + "hello" + ' ' + "world" + '\n';
> // OR
> std::cout << std::string("") + "hello" + ' ' + "world" + '\n';
>
>

I'll search the options to see if I can configure the
standard used
Thanks

Melzzzzz

unread,
Sep 21, 2019, 11:03:22 AM9/21/19
to
On 2019-09-21, Soviet_Mario <Sovie...@CCCP.MIR> wrote:
> On 20/09/2019 20:52, Paavo Helde wrote:
>> On 20.09.2019 19:05, Soviet_Mario wrote:
>>> what's the meaning of that suffix 's' after the literal
>>> char string ?
>>> I've never seen that modifier :\
>>
>> I hoped that the line "using namespace
>> std::literals::string_literals" would give a hint or at
>> least provide something to google. But apparently not.
>
> ah...okay, no did not even suspect such feature before
>
>>
>> Anyway, "abc"s is a std::string literal. You know, these are
>> the kind of literals one should use in C++.
>
> Good thing a native constant std::string !! I'll search
> literals spread in code to replace with this new native type.
>
> Uh another related question. When one uses a true string
> literal "ABC"s to just intialize a variable string, instead
> of a "ABC" char *, a more efficient code is generated ?

I guess, what's the point if not?
>
>
>
>
>>
>>
>
>


--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala

Paavo Helde

unread,
Sep 21, 2019, 12:08:30 PM9/21/19
to
On 21.09.2019 12:44, Soviet_Mario wrote:
>
> Uh another related question. When one uses a true string literal "ABC"s
> to just intialize a variable string, instead of a "ABC" char *, a more
> efficient code is generated ?

Why do you want to know? The difference, even if existing, would be
minuscule and most probably compiler, platform and optimization level
dependent. You should not take such concerns into account when choosing
how to write your code.

Anyway, initializing a std::string variable directly by a std::string
literal avoids one conversion involving one strlen() call, at least
conceptually, so my wild guess is it should be as fast as or faster than
using a char* literal.

David Brown

unread,
Sep 21, 2019, 1:07:53 PM9/21/19
to
On 21/09/2019 11:50, Soviet_Mario wrote:
> On 20/09/2019 21:03, Keith Thompson wrote:
>> Paavo Helde <myfir...@osa.pri.ee> writes:
>>> On 20.09.2019 1:22, Soviet_Mario wrote:
>> [...]
>>>> the aim would be to allow "mixed" multiple chain operation in composing
>>>> strings in a sequence, with at least one STD::STRING somewhere in the
>>>> sequence, but also one or more simple native literals (CHAR *)
>>>> consecutive in it.
>>>
>>> This is currently working:
>>>
>>> #include <string>
>>> using namespace std::literals::string_literals;
>>>
>>> std::string foo() {
>>>     return "full "s + "moon"s;
>>> }
>>>
>>> std::string bar(const char* a, const char* b) {
>>>     return ""s + a + b;
>>> }
>>
>> "..."s was added in C++14.
>
> oh, I see ... installed QT reports C++11 if I'm not wrong.
> Dunno if free upgrades are available (i have the free version)
>
> On the system the installed compiler versions are :
>
> GCC 6.3.0-18  and  GCC 4:6.3.0-4  (I don't think QT ships a compiler of
> its own in the free version)
>

AFAIK QT never ships with any compiler, no matter what license you use.
It is entirely up to /you/ which compiler you use, and what settings you
pick for it, including the C++ standard to use.


Chris Vine

unread,
Sep 21, 2019, 7:28:52 PM9/21/19
to
However a std::string object cannot be constexpr because it has a
non-trivial destructor, whereas a C string literal is constexpr.
Subject to the small string optimization, std::string involves an
allocation, so there are definitely cases where C string literals are a
better choice (and cases where they are not).

By contrast, std::string_view can be constexpr, where it references
a C string literal.

Paavo Helde

unread,
Sep 22, 2019, 4:30:59 AM9/22/19
to
Right, I had forgotten about string_view (again...). So, for potentially
best performance, one could use

using namespace std::literals::string_view_literals;

and

"abc"sv

(this is however a C++17 addition, so might not yet be available
everywhere).

"https://en.cppreference.com/w/cpp/string/basic_string_view/operator%22%22sv"






Soviet_Mario

unread,
Sep 22, 2019, 7:38:49 AM9/22/19
to
exactly my thought : i was suspecting a "template-like"
resolution at compile time instead of calling a constructor
at run-time.
Using native const-literals could be resolved at least
partially at compile time (no actual conversion at all).

Unluckily, I did not discover whether and how to make QT
creator free edition to support the standard 2014. It uses
C++_X11 or sth similar.
And don't recognize the "s" suffix (it complaints unexpected
identifier after the literal).

To be honest, I'm not sure that the problem is QT ide in
itself or the compiler it relies upon (not brand new). Maybe
upgrading the compiler version would convince the IDE to use
the more recent standard ??? dunno.

Soviet_Mario

unread,
Sep 22, 2019, 7:42:04 AM9/22/19
to
In fact it recognized the currently pre-installed version of
GCC (both in Debian and in MX)

> It is entirely up to /you/ which compiler
> you use, and what settings you pick for it, including the
> C++ standard to use.

I just accepted the result of initial scan during QT
installation, which recognized every installed compiler.

Paavo Helde

unread,
Sep 22, 2019, 8:58:07 AM9/22/19
to
On 22.09.2019 14:38, Soviet_Mario wrote:
> Unluckily, I did not discover whether and how to make QT creator free
> edition to support the standard 2014. It uses C++_X11 or sth similar.
> And don't recognize the "s" suffix (it complaints unexpected identifier
> after the literal).

If your compiler does not support std::string literals, you should have
got an error already much earlier, at the "using namespace ..." line.


Soviet_Mario

unread,
Sep 22, 2019, 9:02:32 AM9/22/19
to
yes ... and normally the intelligence opens a popup with
acessible methods and members when it recognizes some valid
header file added, this time it remained silent.

Jorgen Grahn

unread,
Sep 27, 2019, 6:14:45 AM9/27/19
to
On Fri, 2019-09-20, Soviet_Mario wrote:
> On 20/09/2019 11:52, Bo Persson wrote:
...
>> If the strings ARE literals, you don't even need the + to
>> concatenate them. Consecutive literals are combined by the
>> preprocessor:
>>
>> std::string s = "Hello"  ", "  "World!";
>
> no, actually a mixture of std::string variables and some
> literals, to build variable error messages.
>
> I'd like a uniform notation when mixing this sort of data
> ... but not functional notation, rather heavy when chaining
> a lot of small fragments.
>
> I'm trying to avoid per-use of sprintf and asprintf ...
> maybe I'll have to resort to them. The format string is
> rather obscure, but later the comma notation of the variadic
> list is very short and clear.

Also consider using stream output using << -- things like these (I
think you mentioned formatting error messages elsewhere in the thread)
are the reason the feature exists. Format to a temporary stringstream
if needed.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
0 new messages