What is the difference between initializing with = and initializing with {}? - c++

You can initialize a variable using = . For example:
int a = 1000;
C++ 11 introduced an extra notation {} . For example:
int a {1000};
According to Programming: Principles and Practices by Bjarne Stroustrup:
C++11 introduced an initialization notation that outlaws narrowing conversions.
I wanted to check out this cool feature. And I typed a piece of code twice:
#include "std_lib_facilities.h" | #include "std_lib_facilities.h"
|
int main() | int main()
|
{ | {
int x = 254; | int x {254};
char y = x; | char y {x};
int z = y; | int z {y};
|
cout << "x = " << x << '\n' | cout << "x = " << x << '\n'
<< "y = " << y << '\n' | << "y = " << y << '\n'
<< "z = " << z << '\n'; | << "z = " << z << '\n';
|
} | }
The code on the left uses = whereas the code on the right uses {}
But the code on the right hand side loses some information even after using {}. Thus the output is same in both pieces of code:
x = 254
y = ■
z = -2
So, what's the difference between initializing with = and initializing with {} ?
EDIT: My question may or may not be a duplicate. I'm just a beginner and I do not even understand the code of the possibly original question. I'm no judge. Even if it's a duplicate, I cannot understand any answers of that question. I feel that this question should be treated as an original one since I would understand simple language opposed to some high-level words of that question's answer.

What is the difference between initializing with = and initializing with {}?
In general, the difference is that the former is copy initialization and the latter is direct - list initialization. The linked online reference describes all three forms of initialization in detail. In particular, there is the difference that you already quoted; List initialization may not be used with narrowing conversions.
But the code on the right hand side loses some information even after using {}
The program on the right side is ill-formed.
As mentioned, the standard does not allow narrowing conversions in the context of list initialization. int to char is a narrowing conversion.
Because the program is ill-formed, the standard does not guarantee its behaviour except that a compiler is required to emit a diagnostic message. For example, g++-5.3.0 will say:
warning: narrowing conversion of 'x' from 'int' to 'char' inside { } [-Wnarrowing]
May you please elaborate on the "ill-formed" part?
Standard says that the program shall not do X. Your program does X. Therefore it violates the standard which makes the program ill-formed. Here, X is:
If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.
The program on the left is not ill-formed. However it, just like the program on the right side, does assign a value to char y that is not representable by the char type (it could be representable in some implementation where char is an unsigned type, but given the output, that appears not to be the case for your implementation). When an unrepresentable value is converted to a signed type, the resulting value is implementation defined.

Related

Is reinterpret_cast only made for type punning? [duplicate]

I am little confused with the applicability of reinterpret_cast vs static_cast. From what I have read the general rules are to use static cast when the types can be interpreted at compile time hence the word static. This is the cast the C++ compiler uses internally for implicit casts also.
reinterpret_casts are applicable in two scenarios:
convert integer types to pointer types and vice versa
convert one pointer type to another. The general idea I get is this is unportable and should be avoided.
Where I am a little confused is one usage which I need, I am calling C++ from C and the C code needs to hold on to the C++ object so basically it holds a void*. What cast should be used to convert between the void * and the Class type?
I have seen usage of both static_cast and reinterpret_cast? Though from what I have been reading it appears static is better as the cast can happen at compile time? Though it says to use reinterpret_cast to convert from one pointer type to another?
The C++ standard guarantees the following:
static_casting a pointer to and from void* preserves the address. That is, in the following, a, b and c all point to the same address:
int* a = new int();
void* b = static_cast<void*>(a);
int* c = static_cast<int*>(b);
reinterpret_cast only guarantees that if you cast a pointer to a different type, and then reinterpret_cast it back to the original type, you get the original value. So in the following:
int* a = new int();
void* b = reinterpret_cast<void*>(a);
int* c = reinterpret_cast<int*>(b);
a and c contain the same value, but the value of b is unspecified. (in practice it will typically contain the same address as a and c, but that's not specified in the standard, and it may not be true on machines with more complex memory systems.)
For casting to and from void*, static_cast should be preferred.
One case when reinterpret_cast is necessary is when interfacing with opaque data types. This occurs frequently in vendor APIs over which the programmer has no control. Here's a contrived example where a vendor provides an API for storing and retrieving arbitrary global data:
// vendor.hpp
typedef struct _Opaque * VendorGlobalUserData;
void VendorSetUserData(VendorGlobalUserData p);
VendorGlobalUserData VendorGetUserData();
To use this API, the programmer must cast their data to VendorGlobalUserData and back again. static_cast won't work, one must use reinterpret_cast:
// main.cpp
#include "vendor.hpp"
#include <iostream>
using namespace std;
struct MyUserData {
MyUserData() : m(42) {}
int m;
};
int main() {
MyUserData u;
// store global data
VendorGlobalUserData d1;
// d1 = &u; // compile error
// d1 = static_cast<VendorGlobalUserData>(&u); // compile error
d1 = reinterpret_cast<VendorGlobalUserData>(&u); // ok
VendorSetUserData(d1);
// do other stuff...
// retrieve global data
VendorGlobalUserData d2 = VendorGetUserData();
MyUserData * p = 0;
// p = d2; // compile error
// p = static_cast<MyUserData *>(d2); // compile error
p = reinterpret_cast<MyUserData *>(d2); // ok
if (p) { cout << p->m << endl; }
return 0;
}
Below is a contrived implementation of the sample API:
// vendor.cpp
static VendorGlobalUserData g = 0;
void VendorSetUserData(VendorGlobalUserData p) { g = p; }
VendorGlobalUserData VendorGetUserData() { return g; }
The short answer:
If you don't know what reinterpret_cast stands for, don't use it. If you will need it in the future, you will know.
Full answer:
Let's consider basic number types.
When you convert for example int(12) to unsigned float (12.0f) your processor needs to invoke some calculations as both numbers has different bit representation. This is what static_cast stands for.
On the other hand, when you call reinterpret_cast the CPU does not invoke any calculations. It just treats a set of bits in the memory like if it had another type. So when you convert int* to float* with this keyword, the new value (after pointer dereferecing) has nothing to do with the old value in mathematical meaning (ignoring the fact that it is undefined behavior to read this value).
Be aware that reading or modifying values after reinterprt_cast'ing are very often Undefined Behavior. In most cases, you should use pointer or reference to std::byte (starting from C++17) if you want to achieve the bit representation of some data, it is almost always a legal operation. Other "safe" types are char and unsigned char, but I would say it shouldn't be used for that purpose in modern C++ as std::byte has better semantics.
Example: It is true that reinterpret_cast is not portable because of one reason - byte order (endianness). But this is often surprisingly the best reason to use it. Let's imagine the example: you have to read binary 32bit number from file, and you know it is big endian. Your code has to be generic and works properly on big endian (e.g. some ARM) and little endian (e.g. x86) systems. So you have to check the byte order. It is well-known on compile time so you can write constexpr function: You can write a function to achieve this:
/*constexpr*/ bool is_little_endian() {
std::uint16_t x=0x0001;
auto p = reinterpret_cast<std::uint8_t*>(&x);
return *p != 0;
}
Explanation: the binary representation of x in memory could be 0000'0000'0000'0001 (big) or 0000'0001'0000'0000 (little endian). After reinterpret-casting the byte under p pointer could be respectively 0000'0000 or 0000'0001. If you use static-casting, it will always be 0000'0001, no matter what endianness is being used.
EDIT:
In the first version I made example function is_little_endian to be constexpr. It compiles fine on the newest gcc (8.3.0) but the standard says it is illegal. The clang compiler refuses to compile it (which is correct).
The meaning of reinterpret_cast is not defined by the C++ standard. Hence, in theory a reinterpret_cast could crash your program. In practice compilers try to do what you expect, which is to interpret the bits of what you are passing in as if they were the type you are casting to. If you know what the compilers you are going to use do with reinterpret_cast you can use it, but to say that it is portable would be lying.
For the case you describe, and pretty much any case where you might consider reinterpret_cast, you can use static_cast or some other alternative instead. Among other things the standard has this to say about what you can expect of static_cast (§5.2.9):
An rvalue of type “pointer to cv void” can be explicitly converted to a pointer to object type. A value of type pointer to object converted to “pointer to cv void” and back to the original pointer type will have its original value.
So for your use case, it seems fairly clear that the standardization committee intended for you to use static_cast.
One use of reinterpret_cast is if you want to apply bitwise operations to (IEEE 754) floats. One example of this was the Fast Inverse Square-Root trick:
https://en.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code
It treats the binary representation of the float as an integer, shifts it right and subtracts it from a constant, thereby halving and negating the exponent. After converting back to a float, it's subjected to a Newton-Raphson iteration to make this approximation more exact:
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the deuce?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
This was originally written in C, so uses C casts, but the analogous C++ cast is the reinterpret_cast.
Here is a variant of Avi Ginsburg's program which clearly illustrates the property of reinterpret_cast mentioned by Chris Luengo, flodin, and cmdLP: that the compiler treats the pointed-to memory location as if it were an object of the new type:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class A
{
public:
int i;
};
class B : public A
{
public:
virtual void f() {}
};
int main()
{
string s;
B b;
b.i = 0;
A* as = static_cast<A*>(&b);
A* ar = reinterpret_cast<A*>(&b);
B* c = reinterpret_cast<B*>(ar);
cout << "as->i = " << hex << setfill('0') << as->i << "\n";
cout << "ar->i = " << ar->i << "\n";
cout << "b.i = " << b.i << "\n";
cout << "c->i = " << c->i << "\n";
cout << "\n";
cout << "&(as->i) = " << &(as->i) << "\n";
cout << "&(ar->i) = " << &(ar->i) << "\n";
cout << "&(b.i) = " << &(b.i) << "\n";
cout << "&(c->i) = " << &(c->i) << "\n";
cout << "\n";
cout << "&b = " << &b << "\n";
cout << "as = " << as << "\n";
cout << "ar = " << ar << "\n";
cout << "c = " << c << "\n";
cout << "Press ENTER to exit.\n";
getline(cin,s);
}
Which results in output like this:
as->i = 0
ar->i = 50ee64
b.i = 0
c->i = 0
&(as->i) = 00EFF978
&(ar->i) = 00EFF974
&(b.i) = 00EFF978
&(c->i) = 00EFF978
&b = 00EFF974
as = 00EFF978
ar = 00EFF974
c = 00EFF974
Press ENTER to exit.
It can be seen that the B object is built in memory as B-specific data first, followed by the embedded A object. The static_cast correctly returns the address of the embedded A object, and the pointer created by static_cast correctly gives the value of the data field. The pointer generated by reinterpret_cast treats b's memory location as if it were a plain A object, and so when the pointer tries to get the data field it returns some B-specific data as if it were the contents of this field.
One use of reinterpret_cast is to convert a pointer to an unsigned integer (when pointers and unsigned integers are the same size):
int i;
unsigned int u = reinterpret_cast<unsigned int>(&i);
You could use reinterprete_cast to check inheritance at compile time.
Look here:
Using reinterpret_cast to check inheritance at compile time
template <class outType, class inType>
outType safe_cast(inType pointer)
{
void* temp = static_cast<void*>(pointer);
return static_cast<outType>(temp);
}
I tried to conclude and wrote a simple safe cast using templates.
Note that this solution doesn't guarantee to cast pointers on a functions.
First you have some data in a specific type like int here:
int x = 0x7fffffff://==nan in binary representation
Then you want to access the same variable as an other type like float:
You can decide between
float y = reinterpret_cast<float&>(x);
//this could only be used in cpp, looks like a function with template-parameters
or
float y = *(float*)&(x);
//this could be used in c and cpp
BRIEF: it means that the same memory is used as a different type. So you could convert binary representations of floats as int type like above to floats. 0x80000000 is -0 for example (the mantissa and exponent are null but the sign, the msb, is one. This also works for doubles and long doubles.
OPTIMIZE: I think reinterpret_cast would be optimized in many compilers, while the c-casting is made by pointerarithmetic (the value must be copied to the memory, cause pointers couldn't point to cpu- registers).
NOTE: In both cases you should save the casted value in a variable before cast! This macro could help:
#define asvar(x) ({decltype(x) __tmp__ = (x); __tmp__; })
Quick answer: use static_cast if it compiles, otherwise resort to reinterpret_cast.
Read the FAQ! Holding C++ data in C can be risky.
In C++, a pointer to an object can be converted to void * without any casts. But it's not true the other way round. You'd need a static_cast to get the original pointer back.

Type modifiers alternative syntax [duplicate]

What is the difference between
(type)value
and
type(value)
in C++?
There is no difference; per the standard (§5.2.3):
A simple-type-specifier (7.1.5) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).
Since the question specified the difference between type(value) and (type)value, there is absolutely no difference.
If and only if you're dealing with a comma-separated list of values can there be a difference. In this case:
If the expression list specifies more than a single value, the type shall be a class with a suitably declared constructor (8.5, 12.1), and the expression T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2, ...); for some invented temporary variable t, with the result being the value of t as an rvalue.
As Troubadour pointed out, there are a certain names of types for which the type(value) version simply won't compile. For example:
char *a = (char *)string;
will compile, but:
char *a = char *(string);
will not. The same type with a different name (e.g., created with a typedef) can work though:
typedef char *char_ptr;
char *a = char_ptr(string);
There is no difference; the C++ standard (1998 and 2003 editions) is clear about this point. Try the following program, make sure you use a compiler that's compliant, such as the free preview at http://comeaucomputing.com/tryitout/.
#include <cstdlib>
#include <string>
int main() {
int('A'); (int) 'A'; // obvious
(std::string) "abc"; // not so obvious
unsigned(a_var) = 3; // see note below
(long const&) a_var; // const or refs, which T(v) can't do
return EXIT_SUCCESS;
}
Note: unsigned(a_var) is different, but does show one way those exact tokens can mean something else. It is declaring a variable named a_var of type unsigned, and isn't a cast at all. (If you're familiar with pointers to functions or arrays, consider how you have to use a parens around p in a type like void (*pf)() or int (*pa)[42].)
(Warnings are produced since these statements don't use the value and in a real program that'd almost certainly be an error, but everything still works. I just didn't have the heart to change it after making everything line up.)
There is no difference when both are casts, but sometimes 'type(value)' is not a cast.
Here's an example from standard draft N3242, section 8.2.1:
struct S
{
S(int);
};
void foo(double a)
{
S w( int(a) ); // function declaration
S y( (int)a ); // object declaration
}
In this case 'int(a)' is not a cast because 'a' is not a value, it is a parameter name surrounded by redundant parentheses. The document states
The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in 6.8 can also occur in the context
of a declaration. In that context, the choice is between a function
declaration with a redundant set of parentheses around a parameter
name and an object declaration with a function-style cast as the
initializer. Just as for the ambiguities mentioned in 6.8, the
resolution is to consider any construct that could possibly be a
declaration a declaration.
In c there is no type (value), while in c/c++ both type (value) and (type) value are allowed.
To illustrate your options in C++ (only one has a safety check)
#include<boost/numeric/conversion/cast.hpp>
using std::cout;
using std::endl;
int main(){
float smallf = 100.1;
cout << (int)smallf << endl; // outputs 100 // c cast
cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast
cout << static_cast<int>(smallf) << endl; // outputs 100
// cout << static_cast<int&>(smallf) << endl; // not allowed
cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563
cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100
float bigf = 1.23e12;
cout << (int)bigf << endl; // outputs -2147483648
cout << int(bigf) << endl; // outputs -2147483648
cout << static_cast<int>(bigf) << endl; // outputs -2147483648
// cout << static_cast<int&>(bigf) << endl; // not allowed
cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083
cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion
}

C++ Assignment to variable of summation between curly brackets

I'm currently implementing a class for an assignment for my C++ course,
but there is one thing I don't fully grasp. As an example I'll use integers, to make this question more general.
Let's say we have the following code:
#include <iostream>
int main{
int p = { 1 + 2 + 3 };
int q = 1 + 2 + 3;
std::cout << p << " - " << q << std::endl;
return 0;
}
Why is the value for both p and q equal? What is the purpose of the curly brackets? Is there any difference in the way the program is executed or in terms of performance? I'm having a hard time finding the answer to these questions online so thought I'd ask it here.
For a scalar type, all of these syntaxes:
T p = e;
T p(e);
T p{e};
T p = {e};
mean that p is initialized with the value of e. (These different syntaxes can have different meanings when T is a class type.)
However, with the brace syntax, there is an additional constraint that the conversion must not be narrowing:
int p = 2.5; // ok
int q = {2.5}; // error
This check is done at compile time, so it should have no effect on performance at run time.

What is the compiler doing with parameters vs without parameters? [duplicate]

This question already has answers here:
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 4 years ago.
I have a non important question about compilers for C++. The following code outputs
1
2
3
and I can't figure out why. What difference does declaring it with empty parameters make to no parenthesis at all?
#include <iostream>
using namespace std;
int main()
{
int x;
cout << x << endl;
int y();
cout << y << endl;
int z(2);
cout << z << endl;
return 0;
}
The compiler is g++.
The 1st one, x is default initialized with indeterminate value, then cout << x leads to undefined behavior, means anything is possible.
Default initialization of non-class variables with automatic and dynamic storage duration produces objects with indeterminate values
The 2nd one, int y(); declares a function named y, which has no argument and returns int. For cout << y, y will decay to function pointer, which could convert to bool implicitly and then you'll get 1 (i.e. true. You can use std::boolalpha like std::cout << std::boolalpha << y to get the output true).
The 3rd one, z is direct initialized with value 2, then cout << z you'll get 2.
LIVE sample with clang, note all the warning messages the compiler gives.

printing out unordered map values prints out address [duplicate]

Why is the output of the below program what it is?
#include <iostream>
using namespace std;
int main(){
cout << "2+3 = " <<
cout << 2 + 3 << endl;
}
produces
2+3 = 15
instead of the expected
2+3 = 5
This question has already gone multiple close/reopen cycles.
Before voting to close, please consider this meta discussion about this issue.
Whether intentionally or by accident, you have << at the end of the first output line, where you probably meant ;. So you essentially have
cout << "2+3 = "; // this, of course, prints "2+3 = "
cout << cout; // this prints "1"
cout << 2 + 3; // this prints "5"
cout << endl; // this finishes the line
So the question boils down to this: why does cout << cout; print "1"?
This turns out to be, perhaps surprisingly, subtle. std::cout, via its base class std::basic_ios, provides a certain type conversion operator that is intended to be used in boolean context, as in
while (cout) { PrintSomething(cout); }
This is a pretty poor example, as it's difficult to get output to fail - but std::basic_ios is actually a base class for both input and output streams, and for input it makes much more sense:
int value;
while (cin >> value) { DoSomethingWith(value); }
(gets out of the loop at end of stream, or when stream characters do not form a valid integer).
Now, the exact definition of this conversion operator has changed between C++03 and C++11 versions of the standard. In older versions, it was operator void*() const; (typically implemented as return fail() ? NULL : this;), while in newer it's explicit operator bool() const; (typically implemented simply as return !fail();). Both declarations work fine in a boolean context, but behave differently when (mis)used outside of such context.
In particular, under C++03 rules, cout << cout would be interpreted as cout << cout.operator void*() and print some address. Under C++11 rules, cout << cout should not compile at all, as the operator is declared explicit and thus cannot participate in implicit conversions. That was in fact the primary motivation for the change - preventing nonsensical code from compiling. A compiler that conforms to either standard would not produce a program that prints "1".
Apparently, certain C++ implementations allow mixing and matching the compiler and the library in such a way that produces non-conforming outcome (quoting #StephanLechner: "I found a setting in xcode which produces 1, and another setting that yields an address: Language dialect c++98 combined with "Standard library libc++ (LLVM standard library with c++11 support)" yields 1, whereas c++98 combined with libstdc (gnu c++ standard library) yields an address;"). You can have a C++03-style compiler that doesn't understand explicit conversion operators (which are new in C++11) combined with a C++11-style library that defines the conversion as operator bool(). With such a mix, it becomes possible for cout << cout to be interpreted as cout << cout.operator bool(), which in turn is simply cout << true and prints "1".
As Igor says, you get this with a C++11 library, where std::basic_ios has the operator bool instead of the operator void*, but somehow isn't declared (or treated as) explicit. See here for the correct declaration.
For example, a conforming C++11 compiler will give the same result with
#include <iostream>
using namespace std;
int main() {
cout << "2+3 = " <<
static_cast<bool>(cout) << 2 + 3 << endl;
}
but in your case, the static_cast<bool> is being (wrongly) allowed as an implicit conversion.
Edit:
Since this isn't usual or expected behaviour, it might be useful to know your platform, compiler version, etc.
Edit 2: For reference, the code would usually be written either as
cout << "2+3 = "
<< 2 + 3 << endl;
or as
cout << "2+3 = ";
cout << 2 + 3 << endl;
and it's mixing the two styles together that exposed the bug.
The reason for the unexpected output is a typo. You probably meant
cout << "2+3 = "
<< 2 + 3 << endl;
If we ignore the strings that have the expected output, we are left with:
cout << cout;
Since C++11, this is ill-formed. std::cout is not implicitly convertible to anything that std::basic_ostream<char>::operator<< (or a non member overload) would accept. Therefore a standards conforming compiler must at least warn you for doing this. My compiler refused to compile your program.
std::cout would be convertible to bool, and the bool overload of the stream input operator would have the observed output of 1. However, that overload is explicit, so it shouldn't allow an implicit conversion. It appears that your compiler/standard library implementation doesn't strictly conform to the standard.
In a pre-C++11 standard, this is well formed. Back then std::cout had an implicit conversion operator to void* which has a stream input operator overload. The output for that would however be different. it would print the memory address of the std::cout object.
The posted code should not compile for any C++11 (or later conformant compiler), but it should compile without even a warning on pre C++11 implementations.
The difference is that C++11 made the convertion of a stream to a bool explicit:
C.2.15 Clause 27: Input/output library [diff.cpp03.input.output]
27.7.2.1.3, 27.7.3.4, 27.5.5.4
Change: Specify use of explicit in existing boolean conversion operators
Rationale: Clarify intentions, avoid workarounds.
Effect on original feature: Valid C++ 2003 code that relies on implicit boolean conversions will fail to
compile with this International Standard. Such conversions occur in the following conditions:
passing a value to a function that takes an argument of type bool;...
ostream operator << is defined with a bool parameter. As a conversion to bool existed (and was not explicit) is pre-C++11, cout << cout was translated to cout << true which yields 1.
And according to C.2.15, this should not longer compile starting with C++11.
You can easily debug your code this way. When you use cout your output is buffered so you can analyse it like this:
Imagine first occurence of cout represents the buffer and operator << represents appending to the end of the buffer. Result of operator << is output stream, in your case cout. You start from:
cout << "2+3 = " << cout << 2 + 3 << endl;
After applying the above stated rules you get a set of actions like this:
buffer.append("2+3 = ").append(cout).append(2 + 3).append(endl);
As I said before the result of buffer.append() is buffer. At the begining your buffer is empty and you have the following statement to process:
statement: buffer.append("2+3 = ").append(cout).append(2 + 3).append(endl);
buffer: empty
First you have buffer.append("2+3 = ") which puts the given string directly into the buffer and becomes buffer. Now your state looks like this:
statement: buffer.append(cout).append(2 + 3).append(endl);
buffer: 2+3 =
After that you continue to analyze your statement and you come across cout as argument to append to the end of buffer. The cout is treated as 1 so you will append 1 to the end of your buffer. Now you are in this state:
statement: buffer.append(2 + 3).append(endl);
buffer: 2+3 = 1
Next thing you have in buffer is 2 + 3 and since addition has higher precedence than output operator you will first add these two numbers and then you will put the result in buffer. After that you get:
statement: buffer.append(endl);
buffer: 2+3 = 15
Finally you add value of endl to the end of the buffer and you have:
statement:
buffer: 2+3 = 15\n
After this process the characters from the buffer are printed from the buffer to standard output one by one. So the result of your code is 2+3 = 15. If you look at this you get additional 1 from cout you tried to print. By removing << cout from your statement you will get the desired output.