Rectangle 27 133

Conversion Operators (also known as User Defined Conversions)

In C++ you can create conversion operators, operators that allow the compiler to convert between your types and other defined types. There are two types of conversion operators, implicit and explicit ones.

An implicit conversion operator allows the compiler to implicitly convert (like the conversion between int and long) the value of a user-defined type to some other type.

The following is a simple class with an implicit conversion operator:

class my_string {
public:
  operator const char*() const {return data_;} // This is the conversion operator
private:
  const char* data_;
};

Implicit conversion operators, like one-argument constructors, are user-defined conversions. Compilers will grant one user-defined conversion when trying to match a call to an overloaded function.

void f(const char*);

my_string str;
f(str); // same as f( str.operator const char*() )

At first this seems very helpful, but the problem with this is that the implicit conversion even kicks in when it isnt expected to. In the following code, void f(const char*) will be called because my_string() is not an lvalue, so the first does not match:

void f(my_string&);
void f(const char*);

f(my_string());

Beginners easily get this wrong and even experienced C++ programmers are sometimes surprised because the compiler picks an overload they didnt suspect. These problems can be mitigated by explicit conversion operators.

Unlike implicit conversion operators, explicit conversion operators will never kick in when you don't expect them to. The following is a simple class with an explicit conversion operator:

class my_string {
public:
  explicit operator const char*() const {return data_;}
private:
  const char* data_;
};

Notice the explicit. Now when you try to execute the unexpected code from the implicit conversion operators, you get a compiler error:

To invoke the explicit cast operator, you have to use static_cast, a C-style cast, or a constructor style cast ( i.e. T(value) ).

However, there is one exception to this: The compiler is allowed to implicitly convert to bool. In addition, the compiler is not allowed to do another implicit conversion after it converts to bool (a compiler is allowed to do 2 implicit conversions at a time, but only 1 user-defined conversion at max).

Because the compiler will not cast "past" bool, explicit conversion operators now remove the need for the Safe Bool idiom. For example, smart pointers before C++11 used the Safe Bool idiom to prevent conversions to integral types. In C++11, the smart pointers use an explicit operator instead because the compiler is not allowed to implicitly convert to an integral type after it explicitly converted a type to bool.

new
delete

Thank you very much, I consider this a fantastic addition to this FAQ! I have incorporated it into the TOC. I also made a very few small changes to your answer, hopefully improving it a bit by doing so. Feel free to roll them back if you disagree.

c++ - What are the basic rules and idioms for operator overloading? - ...

c++ operators operator-overloading c++-faq
Rectangle 27 132

Conversion Operators (also known as User Defined Conversions)

In C++ you can create conversion operators, operators that allow the compiler to convert between your types and other defined types. There are two types of conversion operators, implicit and explicit ones.

An implicit conversion operator allows the compiler to implicitly convert (like the conversion between int and long) the value of a user-defined type to some other type.

The following is a simple class with an implicit conversion operator:

class my_string {
public:
  operator const char*() const {return data_;} // This is the conversion operator
private:
  const char* data_;
};

Implicit conversion operators, like one-argument constructors, are user-defined conversions. Compilers will grant one user-defined conversion when trying to match a call to an overloaded function.

void f(const char*);

my_string str;
f(str); // same as f( str.operator const char*() )

At first this seems very helpful, but the problem with this is that the implicit conversion even kicks in when it isnt expected to. In the following code, void f(const char*) will be called because my_string() is not an lvalue, so the first does not match:

void f(my_string&);
void f(const char*);

f(my_string());

Beginners easily get this wrong and even experienced C++ programmers are sometimes surprised because the compiler picks an overload they didnt suspect. These problems can be mitigated by explicit conversion operators.

Unlike implicit conversion operators, explicit conversion operators will never kick in when you don't expect them to. The following is a simple class with an explicit conversion operator:

class my_string {
public:
  explicit operator const char*() const {return data_;}
private:
  const char* data_;
};

Notice the explicit. Now when you try to execute the unexpected code from the implicit conversion operators, you get a compiler error:

To invoke the explicit cast operator, you have to use static_cast, a C-style cast, or a constructor style cast ( i.e. T(value) ).

However, there is one exception to this: The compiler is allowed to implicitly convert to bool. In addition, the compiler is not allowed to do another implicit conversion after it converts to bool (a compiler is allowed to do 2 implicit conversions at a time, but only 1 user-defined conversion at max).

Because the compiler will not cast "past" bool, explicit conversion operators now remove the need for the Safe Bool idiom. For example, smart pointers before C++11 used the Safe Bool idiom to prevent conversions to integral types. In C++11, the smart pointers use an explicit operator instead because the compiler is not allowed to implicitly convert to an integral type after it explicitly converted a type to bool.

new
delete

Thank you very much, I consider this a fantastic addition to this FAQ! I have incorporated it into the TOC. I also made a very few small changes to your answer, hopefully improving it a bit by doing so. Feel free to roll them back if you disagree.

c++ - What are the basic rules and idioms for operator overloading? - ...

c++ operators operator-overloading c++-faq
Rectangle 27 132

Conversion Operators (also known as User Defined Conversions)

In C++ you can create conversion operators, operators that allow the compiler to convert between your types and other defined types. There are two types of conversion operators, implicit and explicit ones.

An implicit conversion operator allows the compiler to implicitly convert (like the conversion between int and long) the value of a user-defined type to some other type.

The following is a simple class with an implicit conversion operator:

class my_string {
public:
  operator const char*() const {return data_;} // This is the conversion operator
private:
  const char* data_;
};

Implicit conversion operators, like one-argument constructors, are user-defined conversions. Compilers will grant one user-defined conversion when trying to match a call to an overloaded function.

void f(const char*);

my_string str;
f(str); // same as f( str.operator const char*() )

At first this seems very helpful, but the problem with this is that the implicit conversion even kicks in when it isnt expected to. In the following code, void f(const char*) will be called because my_string() is not an lvalue, so the first does not match:

void f(my_string&);
void f(const char*);

f(my_string());

Beginners easily get this wrong and even experienced C++ programmers are sometimes surprised because the compiler picks an overload they didnt suspect. These problems can be mitigated by explicit conversion operators.

Unlike implicit conversion operators, explicit conversion operators will never kick in when you don't expect them to. The following is a simple class with an explicit conversion operator:

class my_string {
public:
  explicit operator const char*() const {return data_;}
private:
  const char* data_;
};

Notice the explicit. Now when you try to execute the unexpected code from the implicit conversion operators, you get a compiler error:

To invoke the explicit cast operator, you have to use static_cast, a C-style cast, or a constructor style cast ( i.e. T(value) ).

However, there is one exception to this: The compiler is allowed to implicitly convert to bool. In addition, the compiler is not allowed to do another implicit conversion after it converts to bool (a compiler is allowed to do 2 implicit conversions at a time, but only 1 user-defined conversion at max).

Because the compiler will not cast "past" bool, explicit conversion operators now remove the need for the Safe Bool idiom. For example, smart pointers before C++11 used the Safe Bool idiom to prevent conversions to integral types. In C++11, the smart pointers use an explicit operator instead because the compiler is not allowed to implicitly convert to an integral type after it explicitly converted a type to bool.

new
delete

Thank you very much, I consider this a fantastic addition to this FAQ! I have incorporated it into the TOC. I also made a very few small changes to your answer, hopefully improving it a bit by doing so. Feel free to roll them back if you disagree.

c++ - What are the basic rules and idioms for operator overloading? - ...

c++ operators operator-overloading c++-faq
Rectangle 27 3

It is probably the printing that is truncating precision, not the conversion from string to double.

cout.precision(10);
cout << "setting longitude: " << this->longitude << endl;

Thanks! This works with precision 16.

@jshah: nope, 14, the sign and dot do not count, but your original code is really hack'ish not using existing functionality (strtod/stod). Also, the double cast is superfluous since that is the return value of atof by definition if you look the man page up.

If you are using C++11 stod() may be a good idea, instead of lexical_cast()

String to Double conversion C++ - Stack Overflow

c++ string double
Rectangle 27 14

The problem is that C++ is a statically-typed language, meaning that if something is declared as a string, it's a string, and if something is declared as a double, it's a double. Unlike other languages like JavaScript or PHP, there is no way to automatically convert from a string to a numeric value because the conversion might not be well-defined. For example, if you try converting the string "Hi there!" to a double, there's no meaningful conversion. Sure, you could just set the double to 0.0 or NaN, but this would almost certainly be masking the fact that there's a problem in the code.

To fix this, don't buffer the file contents into a string. Instead, just read directly into the double:

double lol;
openfile >> lol;

This reads the value directly as a real number, and if an error occurs will cause the stream's .fail() method to return true. For example:

double lol;
openfile >> lol;

if (openfile.fail()) {
    cout << "Couldn't read a double from the file." << endl;
}

If you're not reading from a stream, you need to use a function to perform the conversion, such as atof() from <stdlib.h>.

@Mike: As a beginner, when you're not reading from a stream, but have a string, you need to put it into a stringstream and read from that.

C++ string to double conversion - Stack Overflow

c++ string file double
Rectangle 27 17

Check this article: http://www.fourcc.org/fccyvrgb.php Conversion is quite easy so you probably could write your own function based on this

Y  =      (0.257 * R) + (0.504 * G) + (0.098 * B) + 16

Cr = V =  (0.439 * R) - (0.368 * G) - (0.071 * B) + 128

Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128

Hi Voyager i need some help i have dumped my code which is yv12->rgb565. In the same way i have to perform for yuv444 to rgb888. Please guide me. Please u can look my latest question for the function which converts yuv12->rgb565

Note that there are several standards governing the colorspace that you might encounter in a yuv file (i.e. BT601, BT709, xvYcc) these formauls will give you a viwable image with most of those, but you may need ot change them to get the coplors "right" (you may also have to clip ot scal the input or output values if you have xvYcc or non-8 bit data

How to perform RGB->YUV conversion in C/C++? - Stack Overflow

c++ c rgb yuv
Rectangle 27 17

Check this article: http://www.fourcc.org/fccyvrgb.php Conversion is quite easy so you probably could write your own function based on this

Y  =      (0.257 * R) + (0.504 * G) + (0.098 * B) + 16

Cr = V =  (0.439 * R) - (0.368 * G) - (0.071 * B) + 128

Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128

Hi Voyager i need some help i have dumped my code which is yv12->rgb565. In the same way i have to perform for yuv444 to rgb888. Please guide me. Please u can look my latest question for the function which converts yuv12->rgb565

Note that there are several standards governing the colorspace that you might encounter in a yuv file (i.e. BT601, BT709, xvYcc) these formauls will give you a viwable image with most of those, but you may need ot change them to get the coplors "right" (you may also have to clip ot scal the input or output values if you have xvYcc or non-8 bit data

How to perform RGB->YUV conversion in C/C++? - Stack Overflow

c++ c rgb yuv
Rectangle 27 2

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string str = "-122.39381636393";
    std::cout.precision(20);
    cout << "setting longitude: " << stod(str) << endl;
    return 0;
}

Basically, you would change things like:

setLatitude(string lat){     //this->lat = (double)atof(lat.c_str());     this->lat = stod(lat); }

@jshah: you need to compile with C++11 support, e.g. -std=c++11 in case of gcc and clang.

I'm using g++ -std=c++11 encounterLocation.cpp and getting the same error.

Whats the best way to go about updating g++? yes, mac

String to Double conversion C++ - Stack Overflow

c++ string double
Rectangle 27 3

The double is parsed correctly, but you're most likely seeing it with the wrong precision. How do you output it? Tailor the precision to your need and it will be ok.

Also, you should know that floating point numbers cannot be always accurately represented in memory, so you may end up with (tiny) rounding errors when using float or doubles. But you can usually safely ignore those unless you're planning to send a rocket to the moon.

Thank you Mic. So instead of working with SO, if I perform multiple mathematical calculations on these numbers, it would still retain the precision level right (Ignoring the tiny rounding errors). While performing calculations do I have to worry about setting the precision as well?

@user1549727 No, as long as you're working with doubles the arithmetic will happen at double precision. Be careful not to convert your doubles to floats or integers in intermediate steps though.

Just to clarify: yes, all calculation will be made in double precision, because that's the way data is stored internally. But when you output it, you can use whatever precision suits you. Compiler takes care of performing always best-effort arithmetic: suppose int x and double y, then x/y will be double. But be careful, int x and int y lead to x/y as int and this might not be what you want (e.g. 5/2 == 2 but 5./2 = 2.5).

string to double conversion in C++ - Stack Overflow

c++ type-conversion
Rectangle 27 2

You can use std::stod if you are using C++11.

double myDouble = std::stod(myString);

string to double conversion in C++ - Stack Overflow

c++ type-conversion
Rectangle 27 41

You can convert char to int and viceversa easily because for the machine an int and a char are the same, 8 bits, the only difference comes when they have to be shown in screen, if the number is 65 and is saved as a char, then it will show 'A', if it's saved as a int it will show 65.

With other types things change, because they are stored differently in memory. There's standard function in C that allows you to convert from string to double easily, it's atof. (You need to include stdlib.h)

#include <stdlib.h>

int main()
{
    string word;  
    openfile >> word;
    double lol = atof(word.c_str()); /*c_str is needed to convert string to const char*
                                     previously (the function requires it)*/
    return 0;
}

C++ string to double conversion - Stack Overflow

c++ string file double
Rectangle 27 1

The proper C++11 solution is to use stod - String TO Double. You probably should use a try ... catch around that function as it throws an exception if your string is not a valid number.

However, the code you have, using atof is perfectly [assuming no bugs in your particular standard C library] converting to double (despite the name being Ascii TO Float, it returns a double value), you are just not printing enough digits, use precision or setprecision to inform cout how many digits to use, e.g.

cout << "Setting longitude: " << setprecision(15) << this->longitude << endl;
<iomanip>
setprecision

String to Double conversion C++ - Stack Overflow

c++ string double
Rectangle 27 1

Your root problem is obviously that the conversion from Celsius to Fahrenheit is implemented incorrectly within the loop. I would approach this problem by extracting the "beef" of your application, i.e. the temperature conversion (formula of which is in Wikipedia), into a method of its own:

/**
 * Converts the input Celsius temperature into Fahrenheit degrees, using the
 * formula:
 * 
 * <pre>
 * (degreesCelsius * 1.8) + 32 = degreesFahrenheit
 * </pre>
 * 
 * @param degreesCelsius
 *            temperature in Celsius degrees
 * @return the temperature in Fahrenheit degrees
 */
private static float celsiusToFahrenheit(float degreesCelsius) {
    return (degreesCelsius * 1.8f) + 32.0f;
}

You should separate the calculation from the rest of the code because it:

  • Improves the readability of your code

After you have done the above, the rest of the code only handles the initialization of the range and iterating over it:

// define the range
final int cMin = 30;
final int cMax = 40;

// run the conversion
for (int i = cMax; i >= cMin; i--) {
    float degreesCelsius = (float) i;
    float degreesFahrenheit = celsiusToFahrenheit(degreesCelsius);
    System.out.println(String.format("%.1f\t|\t%.1f", degreesCelsius,
            degreesFahrenheit));
}

Note that I've declared the Celsius degree range as ints because the requirement was an increment of one degree between each conversion. The values are cast into floats before the calculation.

You should avoid magic numbers in your code, which is why the range is defined as a pair of final variables (which you could also parse out from the args array, if you want to accept user input). The range could also be defined as static final fields if you don't expect it to change between runs of the program.

Finally, utility class Formatter is used for outputting the data through String.format(). This makes it easy to change the precision of the float values in the output.

Java Fahrenheit=Celsius Program Issue - Stack Overflow

java
Rectangle 27 50

No, you can't use explicit, but you can do this instead:

class ClassThatOnlyTakesBoolsAndUIntsAsArguments
{
public:
  void Method(bool arg1);
  void Method(unsigned int arg1);

  // Below just an example showing how to do the same thing with more arguments
  void MethodWithMoreParms(bool arg1, SomeType& arg2);
  void MethodWithMoreParms(unsigned int arg1, SomeType& arg2);

private:
  template<typename T>
  void Method(T arg1);

  // Below just an example showing how to do the same thing with more arguments
  template<typename T>
  void MethodWithMoreParms(T arg1, SomeType& arg2);
};

Repeat this pattern for every method that takes the bool or unsigned int. Do not provide an implementation for the templatized version of the method.

This will force the user to always explicitly call the bool or unsigned int version.

Any attempt to call Method with a type other than bool or unsigned int will fail to compile because the member is private, subject to the standard exceptions to visibility rules, of course (friend, internal calls, etc.). If something that does have access calls the private method, you will get a linker error.

Yes, it will disable ALL automatic conversions. Dan wants to "prevent the conversion of parameters for a class method", per the question text, and this method satisfies that. There are ways using template specialization that we could 'map' basic types to specific methods if so desired.

c++ - Can you use keyword explicit to prevent automatic conversion of ...

c++ implicit-conversion explicit
Rectangle 27 15

Conversion is when a value is, um, converted to a different type. The result is a value of the target type, and there are rules for what output value results from what input (of the source type).

int i = 3;
unsigned int j;
j = i; // the value of "i" is converted to "unsigned int".

The result is the unsigned int value that is equal to i modulo UINT_MAX+1, and this rule is part of the language. So, in this case the value (in English) is still "3", but it's an unsigned int value of 3, which is subtly different from a signed int value of 3.

Note that conversion happened automatically, we just used a signed int value in a position where an unsigned int value is required, and the language defines what that means without us actually saying that we're converting. That's called an "implicit conversion".

unsigned int k = (unsigned int)i;
long l = long(i);
unsigned int m = static_cast<unsigned int>(i);

are all casts. Specifically, according to 5.4/2 of the standard, k uses a cast-expression, and according to 5.2.3/1, l uses an equivalent thing (except that I've used a different type). m uses a "type conversion operator" (static_cast), but other parts of the standard refer to those as "casts" too.

User-defined types can define "conversion functions" which provide specific rules for converting your type to another type, and single-arg constructors are used in conversions too:

struct Foo {
    int a;
    Foo(int b) : a(b) {}                   // single-arg constructor
    Foo(int b, int c) : a(b+c) {}          // two-arg constructor
    operator float () { return float(a); } // conversion function
};

Foo f(3,4);              // two-arg constructor
f = static_cast<Foo>(4); // conversion: single-arg constructor is called
float g = f;             // conversion: conversion function is called

Type Conversion/Casting Confusion in C++ - Stack Overflow

c++ type-conversion casting conversion-operator
Rectangle 27 10

#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << stod("  99.999  ") << endl;
}

Output: 99.999 (which is double, whitespace was automatically stripped)

Since C++11 converting string to floating-point values (like double) is available with functions:stof - convert str to a floatstod - convert str to a doublestold - convert str to a long double

As conversion of string to int was also mentioned in the question, there are the following functions in C++11:stoi - convert str to an intstol - convert str to a longstoul - convert str to an unsigned longstoll - convert str to a long longstoull - convert str to an unsigned long long

C++ string to double conversion - Stack Overflow

c++ string file double
Rectangle 27 29

You might also want to try these integer only calculations (should be faster than floats)

#define CLIP(X) ( (X) > 255 ? 255 : (X) < 0 ? 0 : X)

// RGB -> YUV
#define RGB2Y(R, G, B) CLIP(( (  66 * (R) + 129 * (G) +  25 * (B) + 128) >> 8) +  16)
#define RGB2U(R, G, B) CLIP(( ( -38 * (R) -  74 * (G) + 112 * (B) + 128) >> 8) + 128)
#define RGB2V(R, G, B) CLIP(( ( 112 * (R) -  94 * (G) -  18 * (B) + 128) >> 8) + 128)

// YUV -> RGB
#define C(Y) ( (Y) - 16  )
#define D(U) ( (U) - 128 )
#define E(V) ( (V) - 128 )

#define YUV2R(Y, U, V) CLIP(( 298 * C(Y)              + 409 * E(V) + 128) >> 8)
#define YUV2G(Y, U, V) CLIP(( 298 * C(Y) - 100 * D(U) - 208 * E(V) + 128) >> 8)
#define YUV2B(Y, U, V) CLIP(( 298 * C(Y) + 516 * D(U)              + 128) >> 8)

// RGB -> YCbCr
#define CRGB2Y(R, G, B) CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16)
#define CRGB2Cb(R, G, B) CLIP((36962 * (B - CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16) ) >> 16) + 128)
#define CRGB2Cr(R, G, B) CLIP((46727 * (R - CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16) ) >> 16) + 128)

// YCbCr -> RGB
#define CYCbCr2R(Y, Cb, Cr) CLIP( Y + ( 91881 * Cr >> 16 ) - 179 )
#define CYCbCr2G(Y, Cb, Cr) CLIP( Y - (( 22544 * Cb + 46793 * Cr ) >> 16) + 135)
#define CYCbCr2B(Y, Cb, Cr) CLIP( Y + (116129 * Cb >> 16 ) - 226 )

How to perform RGB->YUV conversion in C/C++? - Stack Overflow

c++ c rgb yuv
Rectangle 27 28

You might also want to try these integer only calculations (should be faster than floats)

#define CLIP(X) ( (X) > 255 ? 255 : (X) < 0 ? 0 : X)

// RGB -> YUV
#define RGB2Y(R, G, B) CLIP(( (  66 * (R) + 129 * (G) +  25 * (B) + 128) >> 8) +  16)
#define RGB2U(R, G, B) CLIP(( ( -38 * (R) -  74 * (G) + 112 * (B) + 128) >> 8) + 128)
#define RGB2V(R, G, B) CLIP(( ( 112 * (R) -  94 * (G) -  18 * (B) + 128) >> 8) + 128)

// YUV -> RGB
#define C(Y) ( (Y) - 16  )
#define D(U) ( (U) - 128 )
#define E(V) ( (V) - 128 )

#define YUV2R(Y, U, V) CLIP(( 298 * C(Y)              + 409 * E(V) + 128) >> 8)
#define YUV2G(Y, U, V) CLIP(( 298 * C(Y) - 100 * D(U) - 208 * E(V) + 128) >> 8)
#define YUV2B(Y, U, V) CLIP(( 298 * C(Y) + 516 * D(U)              + 128) >> 8)

// RGB -> YCbCr
#define CRGB2Y(R, G, B) CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16)
#define CRGB2Cb(R, G, B) CLIP((36962 * (B - CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16) ) >> 16) + 128)
#define CRGB2Cr(R, G, B) CLIP((46727 * (R - CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16) ) >> 16) + 128)

// YCbCr -> RGB
#define CYCbCr2R(Y, Cb, Cr) CLIP( Y + ( 91881 * Cr >> 16 ) - 179 )
#define CYCbCr2G(Y, Cb, Cr) CLIP( Y - (( 22544 * Cb + 46793 * Cr ) >> 16) + 135)
#define CYCbCr2B(Y, Cb, Cr) CLIP( Y + (116129 * Cb >> 16 ) - 226 )

How to perform RGB->YUV conversion in C/C++? - Stack Overflow

c++ c rgb yuv
Rectangle 27 15

Objects and values

I think the lvalue-to-rvalue conversion is more than just use an lvalue where an rvalue is required. It can create a copy of a class, and always yields a value, not an object.

I'm using n3485 for "C++11" and n1256 for "C99".

region of data storage in the execution environment, the contents of which can represent values

There's also a bit in C++11/[intro.object]/1

Some objects are polymorphic; the implementation generates information associated with each such object that makes it possible to determine that objects type during program execution. For other objects, the interpretation of the values found therein is determined by the type of the expressions used to access them.

So an object contains a value (can contain).

The full taxonomy / categorization can be found in [basic.lval]; here's a StackOverflow discussion.

Here are the parts about objects:

  • An lvalue ([...]) designates a function or an object. [...]
  • A glvalue (generalized lvalue) is an lvalue or an xvalue.
  • An rvalue ([...]) is an xvalue, a temporary object or subobject thereof, or a value that is not associated with an object.
  • A prvalue (pure rvalue) is an rvalue that is not an xvalue. [...]

Note the phrase "a value that is not associated with an object". Also note that as xvalue-expressions refer to objects, true values must always occur as prvalue-expressions.

As footnote 53 indicates, it should now be called "glvalue-to-prvalue conversion". First, here's the quote:

1 A glvalue of a non-function, non-array type T can be converted to a prvalue. If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior. If T is a non-class type, the type of the prvalue is the cv-unqualified version of T. Otherwise, the type of the prvalue is T.

This first paragraph specifies the requirements and the resulting type of the conversion. It isn't yet concerned with the effects of the conversion (other than Undefined Behaviour).

2 When an lvalue-to-rvalue conversion occurs in an unevaluated operand or a subexpression thereof the value contained in the referenced object is not accessed. Otherwise, if the glvalue has a class type, the conversion copy-initializes a temporary of type T from the glvalue and the result of the conversion is a prvalue for the temporary. Otherwise, if the glvalue has (possibly cv-qualified) type std::nullptr_t, the prvalue result is a null pointer constant. Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.

I'd argue that you'll see the lvalue-to-rvalue conversion most often applied to non-class types. For example,

struct my_class { int m; };

my_class x{42};
my_class y{0};

x = y;

The expression x = y does not apply the lvalue-to-rvalue conversion to y (that would create a temporary my_class, by the way). The reason is that x = y is interpreted as x.operator=(y), which takes y per default by reference, not by value (for reference binding, see below; it cannot bind an rvalue, as that would be a temporary object different from y). However, the default definition of my_class::operator= does apply the lvalue-to-rvalue conversion to x.m.

Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.

So typically, an lvalue-to-rvalue conversion will just read the value from an object. It isn't just a no-op conversion between value (expression) categories; it can even create a temporary by calling a copy constructor. And the lvalue-to-rvalue conversion always returns a prvalue value, not a (temporary) object.

Note that the lvalue-to-rvalue conversion is not the only conversion that converts an lvalue to a prvalue: There's also the array-to-pointer conversion and the function-to-pointer conversion.

Most expressions don't yield objects[[citation needed]]. However, an id-expression can be an identifier, which denotes an entity. An object is an entity, so there are expressions which yield objects:

int x;
x = 5;
x = 5

Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue, array-to-pointer, or function-to-pointer standard conversions are applied to convert the expression to a prvalue.

And /10 about usual arithmetic conversions as well as /3 about user-defined conversions.

I'd love now to quote an operator that "expects a prvalue for that operand", but cannot find any but casts. For example, [expr.dynamic.cast]/2 "If T is a pointer type, v [the operand] shall be a prvalue of a pointer to complete class type".

The usual arithmetic conversions required by many arithmetic operators do invoke an lvalue-to-rvalue conversion indirectly via the standard conversion used. All standard conversions but the three that convert from lvalues to rvalues expect prvalues.

The simple assignment however doesn't invoke the usual arithmetic conversions. It is defined in [expr.ass]/2 as:

In simple assignment (=), the value of the expression replaces that of the object referred to by the left operand.

So although it doesn't explicitly require a prvalue expression on the right hand side, it does require a value. It is not clear to me if this strictly requires the lvalue-to-rvalue conversion. There's an argument that accessing the value of an uninitialized variable should always invoke undefined behaviour (also see CWG 616), no matter if it's by assigning its value to an object or by adding its value to another value. But this undefined behaviour is only required for an lvalue-to-rvalue conversion (AFAIK), which then should be the only way to access the value stored in an object.

If this more conceptual view is valid, that we need the lvalue-to-rvalue conversion to access the value inside an object, then it'd be much easier to understand where it is (and needs to be) applied.

As with simple assignment, there's a discussion whether or not the lvalue-to-rvalue conversion is required to initialize another object:

int x = 42; // initializer is a non-string literal -> prvalue
int y = x;  // initializer is an object / lvalue

Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. Standard conversions will be used, if necessary, to convert the initializer expression to the cv-unqualified version of the destination type; no user-defined conversions are considered. If the conversion cannot be done, the initialization is ill-formed.

However, it also mentioned the value of the initializer expression. Similar to the simple-assignment-expression, we can take this as an indirect invocation of the lvalue-to-rvalue conversion.

If we see lvalue-to-rvalue conversion as a way to access the value of an object (plus the creation of a temporary for class type operands), we understand that it's not applied generally for binding to a reference: A reference is an lvalue, it always refers to an object. So if we bound values to references, we'd need to create temporary objects holding those values. And this is indeed the case if the initializer-expression of a reference is a prvalue (which is a value or a temporary object):

int const& lr = 42; // create a temporary object, bind it to `r`
int&& rv = 42;      // same

Binding a prvalue to an lvalue reference is prohibited, but prvalues of class types with conversion functions that yield lvalue references may be bound to lvalue references of the converted type.

The complete description of reference binding in [dcl.init.ref] is rather long and rather off-topic. I think the essence of it relating to this question is that references refer to objects, therefore no glvalue-to-prvalue (object-to-value) conversion.

As pointer arithmetics are not subject to the usual arithmetic conversions, there's also no lvalue-to-rvalue conversion applied explicitly to pointers as operands (even though their value is used).

It might need a TL;DR

+1 this is very detailed. I don't see indirection covered here, as far as I can tell indirection does not cause an lvalue to revalue conversion but it is not obvious.

That is what I think as well but I have seen this justification used several times to indicate something is undefined behavior like here but I don't see that it applies. I guess the opinion is that any read of a value is an lvalue-to-rvalue conversion which seems too broad.

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

c++ - lvalue to rvalue implicit conversion - Stack Overflow

c++ c++11 implicit-conversion lvalue-to-rvalue
Rectangle 27 31

#include <string>

const char digit_pairs[201] = {
  "00010203040506070809"
  "10111213141516171819"
  "20212223242526272829"
  "30313233343536373839"
  "40414243444546474849"
  "50515253545556575859"
  "60616263646566676869"
  "70717273747576777879"
  "80818283848586878889"
  "90919293949596979899"
};


std::string& itostr(int n, std::string& s)
{
    if(n==0)
    {
        s="0";
        return s;
    }

    int sign = -(n<0);
    unsigned int val = (n^sign)-sign;

    int size;
    if(val>=10000)
    {
        if(val>=10000000)
        {
            if(val>=1000000000)
                size=10;
            else if(val>=100000000)
                size=9;
            else 
                size=8;
        }
        else
        {
            if(val>=1000000)
                size=7;
            else if(val>=100000)
                size=6;
            else
                size=5;
        }
    }
    else 
    {
        if(val>=100)
        {
            if(val>=1000)
                size=4;
            else
                size=3;
        }
        else
        {
            if(val>=10)
                size=2;
            else
                size=1;
        }
    }
    size -= sign;
    s.resize(size);
    char* c = &s[0];
    if(sign)
        *c='-';

    c += size-1;
    while(val>=100)
    {
       int pos = val % 100;
       val /= 100;
       *(short*)(c-1)=*(short*)(digit_pairs+2*pos); 
       c-=2;
    }
    while(val>0)
    {
        *c--='0' + (val % 10);
        val /= 10;
    }
    return s;
}

std::string& itostr(unsigned val, std::string& s)
{
    if(val==0)
    {
        s="0";
        return s;
    }

    int size;
    if(val>=10000)
    {
        if(val>=10000000)
        {
            if(val>=1000000000)
                size=10;
            else if(val>=100000000)
                size=9;
            else 
                size=8;
        }
        else
        {
            if(val>=1000000)
                size=7;
            else if(val>=100000)
                size=6;
            else
                size=5;
        }
    }
    else 
    {
        if(val>=100)
        {
            if(val>=1000)
                size=4;
            else
                size=3;
        }
        else
        {
            if(val>=10)
                size=2;
            else
                size=1;
        }
    }

    s.resize(size);
    char* c = &s[size-1];
    while(val>=100)
    {
       int pos = val % 100;
       val /= 100;
       *(short*)(c-1)=*(short*)(digit_pairs+2*pos); 
       c-=2;
    }
    while(val>0)
    {
        *c--='0' + (val % 10);
        val /= 10;
    }
    return s;
}

This will blow up on systems that disallow unaligned memory accesses (in which case, the first unaligned assignment via *(short*) would cause a segfault), but should work very nicely otherwise.

One important thing to do is to minimize the use of std::string. (Ironic, I know.) In Visual Studio, for example, most calls to methods of std::string are not inlined, even if you specify /Ob2 in compiler options. So even something as trivial as a call to std::string::clear(), which you might expect to be very fast, can take 100 clockticks when linking CRT as a static library, and as much as 300 clockticks when linking as a DLL.

For the same reason, returning by reference is better because it avoids an assignment, a constructor and a destructor.

Thanks for your attempt. On ideone (ideone.com/BCp5r), it scores 18.5 MB/s, about half the speed of sprintf. And with VC++ 2010, it gets about 50 MB/s, about twice the speed of sprintf.

MB/s is a strange metric, especially seeing how you don't remove trailing whitespaces from the string in your implementations. My updated code runs faster than your implementation with x64 VC++ 2005 on Core i7 920 (16.2M ops/s vs. 14.8M ops/s), _ltoa does 8.5M ops/s and sprintf() does 3.85M ops/s.

Your code doesn't properly resize the string, mine does (see lines 81, 198, and 290). I took some shortcuts in the sprintf implementation, I already mentioned that in my question, but I believe the code-to-beat gives exactly the same result as stringstream.

I've fixed the sprintf wrapper as well, to avoid confusion.

BTW, your improved version (ideone.com/GLAbS) gets 41.7 MB/s on ideone, and right around 120 MB/s on VC++ 2010 32-bit.

C++ performance challenge: integer to std::string conversion - Stack O...

c++ performance string integer