I'm working on an output stream class just like ostream. For formatted output I use the << operator taking a reference as argument (e.g. "&int").
Now I want this operator function to accept also int literals like 12345. How can I achieve this? I know there must be a way cause with ostream it works just fine. Ostream also deals with references as described in the documentation on this site but I can also write for example cout << 12345.
Because it's a waste of time and (sometimes) memory. You could just pass it by value. It has the same cost (4 bytes) and it saves you the hidden dereferencing operation that has to be done every time you access something by a reference.
Passing by references is faster for large complex objects because the object does not need to be copied. For tiny objects like int this does not apply. Copying an int is faster than copying a reference to an int and dereferencing it.
However, this only makes a difference if the functions in question are not inlined.
For inlined functions, passing by constant reference and passing by value does not result in different assembly code (only for simple objects!). So if your class is header-only, just don't worry about it.
//...
// [27.6.2.5.2] arithmetic inserters
/**
* @name Arithmetic Inserters
*
* All the @c operator<< functions (aka <em>formatted output
* functions</em>) have some common behavior. Each starts by
* constructing a temporary object of type std::basic_ostream::sentry.
* This can have several effects, concluding with the setting of a
* status flag; see the sentry documentation for more.
*
* If the sentry status is good, the function tries to generate
* whatever data is appropriate for the type of the argument.
*
* If an exception is thrown during insertion, ios_base::badbit
* will be turned on in the stream's error state without causing an
* ios_base::failure to be thrown. The original exception will then
* be rethrown.
*/
//@{
/**
* @brief Basic arithmetic inserters
* @param A variable of builtin type.
* @return @c *this if successful
*
* These functions use the stream's current locale (specifically, the
* @c num_get facet) to perform numeric formatting.
*/
__ostream_type&
operator<<(long __n);
__ostream_type&
operator<<(unsignedlong __n);
__ostream_type&
operator<<(bool __n);
__ostream_type&
operator<<(short __n)
{
ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
if (__fmt & ios_base::oct || __fmt & ios_base::hex)
returnthis->operator<<(static_cast<unsignedlong>
(static_cast<unsignedshort>(__n)));
elsereturnthis->operator<<(static_cast<long>(__n));
}
__ostream_type&
operator<<(unsignedshort __n)
{ returnthis->operator<<(static_cast<unsignedlong>(__n)); }
__ostream_type&
operator<<(int __n)
{
ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
if (__fmt & ios_base::oct || __fmt & ios_base::hex)
returnthis->operator<<(static_cast<unsignedlong>
(static_cast<unsignedint>(__n)));
elsereturnthis->operator<<(static_cast<long>(__n));
}
__ostream_type&
operator<<(unsignedint __n)
{ returnthis->operator<<(static_cast<unsignedlong>(__n)); }
#ifdef _GLIBCXX_USE_LONG_LONG
__ostream_type&
operator<<(longlong __n);
__ostream_type&
operator<<(unsignedlonglong __n);
#endif
__ostream_type&
operator<<(double __f);
__ostream_type&
operator<<(float __f)
{ returnthis->operator<<(static_cast<double>(__f)); }
__ostream_type&
operator<<(longdouble __f);
__ostream_type&
operator<<(constvoid* __p);
//...
27.6.2.5.2 Arithmetic Inserters
operator<<(bool val);
operator<<(short val);
operator<<(unsigned short val);
operator<<(int val);
operator<<(unsigned int val);
operator<<(long val);
operator<<(unsigned long val);
operator<<(float val);
operator<<(double val);
operator<<(long double val);
operator<<(const void* val);
However, this only makes a difference if the functions in question are not inlined.
For inlined functions, passing by constant reference and passing by value does not result in different assembly code (only for simple objects!). So if your class is header-only, just don't worry about it.
You can't know if the compiler really inlines your functions so you do need to worry about it