Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > User defined conversion to builtin type gives l-value?

Reply
Thread Tools

User defined conversion to builtin type gives l-value?

 
 
Arne Mertz
Guest
Posts: n/a
 
      04-11-2009
Hi all, following example:

template <class T, class U>
T foo(U const& u, T const& t)
{
return T temp(u) /= t;
}

gives me an error "'/=' left operand has to be an l-value" on MSVC
2008 express, if T is a builtin type (e.g. double). In my case, U
has an konversion operator to double. If I try the same with T being
a builtin class and either providing a konversion ctor for T or
providing an konversion operator for U, it works.
My question is: is that right according to the standard? I found a
line saying that implicit standard conversions result in l-values,
but as far as i can see this is an explicitly called user defined
conversion or not?

greets
A
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-11-2009
* Arne Mertz:
> Hi all, following example:
>
> template <class T, class U>
> T foo(U const& u, T const& t)
> {
> return T temp(u) /= t;


This is syntactically incorrect.

Perhaps you meant

return T(u)/t;


> }
>
> gives me an error "'/=' left operand has to be an l-value" on MSVC 2008
> express, if T is a builtin type (e.g. double). In my case, U has an
> konversion operator to double. If I try the same with T being a builtin
> class


There are only a few classes that have direct compiler support, they include
typeinfo and some exception classes.

And it's still arguable whether they could be referred to as builtin classes.

Probably you meant "builtin type".


> and either providing a konversion ctor for T or providing an
> konversion operator for U, it works.


You cannot provide a constructor for a built-in type.


> My question is: is that right according to the standard?


Your code should not compile, if that's what you're asking.


> I found a line
> saying that implicit standard conversions result in l-values, but as far
> as i can see this is an explicitly called user defined conversion or not?


Huh?


Cheers & hth.,

- Alf


--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! Just going there is good. Linking
to it is even better! Thanks in advance!
 
Reply With Quote
 
 
 
 
Arne Mertz
Guest
Posts: n/a
 
      04-11-2009
Alf P. Steinbach schrieb:
> * Arne Mertz:
>> Hi all, following example:
>>
>> template <class T, class U>
>> T foo(U const& u, T const& t)
>> {
>> return T temp(u) /= t;

>
> This is syntactically incorrect.
>
> Perhaps you meant
>
> return T(u)/t;


Yes, sorry.
>
>
>> }
>>
>> gives me an error "'/=' left operand has to be an l-value" on MSVC
>> 2008 express, if T is a builtin type (e.g. double). In my case, U has
>> an konversion operator to double. If I try the same with T being a
>> builtin class

>
> There are only a few classes that have direct compiler support, they
> include typeinfo and some exception classes.
>
> And it's still arguable whether they could be referred to as builtin
> classes.
>
> Probably you meant "builtin type".


Nope, sorry, I meant user defined class.
>
>
>> and either providing a konversion ctor for T or providing an
>> konversion operator for U, it works.


>> My question is: is that right according to the standard?

>
> Your code should not compile, if that's what you're asking.
>
>
>> I found a line saying that implicit standard conversions result in
>> l-values, but as far as i can see this is an explicitly called user
>> defined conversion or not?

>
> Huh?
>


Okay, seems I messed it all up a bit. So another try here:


template <class T, class U>
T foo(U const& u, T const& t)
{
return T(u) /= t;
}

class X {};

struct Y
{
Y() {};
Y(X const&) {}; //konversion ctor userdefined->userdefined (1)
Y(int); //konversion ctor builtin->userdefined (2)
Y& operator /= (Y const& rhs) {}
};

struct Z
{
operator Y() const; //konversion op userdefined->userdefined (3)
operator double() const; //konversion op userdefined->builtin (4)
};

int main()
{
X x; Y y; Z z; int i; double d;

foo(x, y); // calls (1), ok.
foo(i, y); // calls (2), ok.

foo(z, y); // calls (3), ok.
foo(z, i); // calls (4), ERROR, because int(z) is l-value

foo(i, d); // calls double(i) /= d; ERROR because double(i) is
l-value
}

as far as I can the conversion in foo is explicit. I could not find
any phrase in the standard saying whether the result of an explicit
conversion is an l-value or an r-value. as it seems, either the
conversion to userdefined types gives l-values, or the userdefined
op/= can be applied to r-values in contrast to the builtin op/=
Which is the case?

greets
A
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-11-2009
* Arne Mertz:
>
> I could not find any
> phrase in the standard saying whether the result of an explicit
> conversion is an l-value or an r-value.


It's an rvalue.


> as it seems, either the
> conversion to userdefined types gives l-values, or the userdefined op/=
> can be applied to r-values in contrast to the builtin op/=


Yes.

Any accessible non-static member function can be applied to a non-const rvalue
of class type.

Note: that includes a compiler-generated operator=.


Cheers & hth.,

- Alf

--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! Just going there is good. Linking
to it is even better! Thanks in advance!
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-11-2009
* Alf P. Steinbach:
> * Arne Mertz:
>>
>> I could not find any phrase in the standard saying whether the result
>> of an explicit conversion is an l-value or an r-value.

>
> It's an rvalue.


More precisely (I didn't register that phrasing) the expression is an rvalue.

The result at run time when the expression is evaluated is an object.

Objects are neither lvalues nor rvalues, only expressions are.


>> as it seems, either the conversion to userdefined types gives
>> l-values, or the userdefined op/= can be applied to r-values in
>> contrast to the builtin op/=

>
> Yes.
>
> Any accessible non-static member function can be applied to a non-const
> rvalue of class type.
>
> Note: that includes a compiler-generated operator=.
>
>
> Cheers & hth.,
>
> - Alf


--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! Just going there is good. Linking
to it is even better! Thanks in advance!
 
Reply With Quote
 
Arne Mertz
Guest
Posts: n/a
 
      04-11-2009
Alf P. Steinbach schrieb:
> * Alf P. Steinbach:
>> * Arne Mertz:
>>>
>>> I could not find any phrase in the standard saying whether the result
>>> of an explicit conversion is an l-value or an r-value.

>>
>> It's an rvalue.

>
> More precisely (I didn't register that phrasing) the expression is an
> rvalue.
>
> The result at run time when the expression is evaluated is an object.
>
> Objects are neither lvalues nor rvalues, only expressions are.
>


Okay, thank you.
In boost:perators this "shorthand" notation is used for one of the
operator-templates, thus preventing those templates to be used with
builtins. Guess I should write a ticket and/or search for a
workaround

greets
A
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      04-11-2009
On 11 Apr., 18:30, Arne Mertz <(E-Mail Removed)> wrote:
> Alf P. Steinbach wrote:
> > Perhaps you meant
> > * return T(u)/t;

>
> Yes, sorry.
>
> [...]
>
> Okay, seems I messed it all up a bit. So another try here:
>
> template <class T, class U>
> T foo(U const& u, T const& t)
> {
> * *return T(u) /= t;
> }


You either write

return T(u) / t; // suggested previously

or you write

T temp = u;
temp /= t;
return temp;

But "/=" doesn't generally work on rvalues. T(u) *is* an rvalue
expression.

Cheers!
SG
 
Reply With Quote
 
Arne Mertz
Guest
Posts: n/a
 
      04-11-2009
SG schrieb:
> On 11 Apr., 18:30, Arne Mertz <(E-Mail Removed)> wrote:
>
> You either write
>
> return T(u) / t; // suggested previously
>
> or you write
>
> T temp = u;
> temp /= t;
> return temp;
>


Unfortunately, *I* write nothing there. The function is part of the
boost libraries (boost/operators.hpp, line 240). It is only used in
the absence of two #defines, so as a workaround I had to check for
those defines and set one of them explicitly.

Greets
A
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-12-2009
On Apr 11, 5:13 pm, Arne Mertz <(E-Mail Removed)> wrote:
> Hi all, following example:


> template <class T, class U>
> T foo(U const& u, T const& t)
> {
> return T temp(u) /= t;
> }


> gives me an error "'/=' left operand has to be an l-value" on
> MSVC 2008 express, if T is a builtin type (e.g. double). In my
> case, U has an konversion operator to double. If I try the
> same with T being a builtin class and either providing a
> konversion ctor for T or providing an konversion operator for
> U, it works. My question is: is that right according to the
> standard? I found a line saying that implicit standard
> conversions result in l-values, but as far as i can see this
> is an explicitly called user defined conversion or not?


Alf's already pointed out a couple of errors in your
formulation: illegal syntax in the example, constructors for a
build in type. Those aren't nits: copy paste the actual code
for code, and as for the others: being able to express yourself
clearly, concisely and precisely in your native language is a
prerequisite to learning any programming language. (I realize
that English probably isn't your native language, judging from
your return address, but in this case, the translation would be
literal to and from any other language: "Es gibt keinen
Constructor für eingebaut Type" in German, as well. And if you
really do have problems with English, the people in
de.comp.lang.iso-c++ are very friendly as well.)

Anyway: I don't know where you found anything saying that
implicit standard conversions result in lvalues. The only
conversions which result in lvalues are those to references, and
none of the standard conversions result in a references. The
only way something like "return T(u) /= t ;" could be legal is
if T had a user defined conversion operator which returned a
reference, or if operator/=() was a member function of T (or a
base class of T). (The latter is actually a frequent case.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      04-12-2009
On Apr 11, 9:34 pm, Arne Mertz <(E-Mail Removed)> wrote:
> SG schrieb:


> > On 11 Apr., 18:30, Arne Mertz <(E-Mail Removed)> wrote:


> > You either write


> > return T(u) / t; // suggested previously


> > or you write


> > T temp = u;
> > temp /= t;
> > return temp;


> Unfortunately, *I* write nothing there. The function is part
> of the boost libraries (boost/operators.hpp, line 240). It is
> only used in the absence of two #defines, so as a workaround I
> had to check for those defines and set one of them explicitly.


Have you actually read the documentation of Boost:perators?
They provide operators for user defined classes. Not in the
best way, of course---you really want to use the Barton and
Nackman trick here, and provide them as friends of a base
class. But that's not the point here: if you instantiate e.g.
operator/ with X as the first template argument, then it is a
pre-condition that X has a member function operator/=.
Otherwise, you're not using the library as specified.

Of course, I can't find any way you could reasonably use the
library as it is specified---you need operator/ to be somewhere
where ADL will find it, and ADL will not look into namespace
boost. (That's why the Barton and Nackman trick is preferred.)
And of course, there really isn't any good reason to not support
classes with operator/= as a free function---arguably, it should
be a free function, because that is the only way to make it
require an lvalue. (On the other hand, operator= can't be a
free function, so you've lost this aspect anyway, and you might
as well go ahead and make them all members. I know I usuallly
do.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
subtle error slows code by 10x (builtin sum()) - replace builtin sumwithout using import? bdb112 Python 2 07-02-2011 03:13 AM
Accessing an element of an array of list of user-defined structure,gives Access Violation PSN C++ 8 06-18-2011 11:09 AM
Type conversion function for user defined type... zaeminkr@gmail.com C++ 1 05-16-2007 09:00 AM
conversion from one user defined type to another Kavya C++ 2 10-31-2006 03:50 AM
#if (defined(__STDC__) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) Oodini C Programming 1 09-27-2005 07:58 PM



Advertisments