473,388 Members | 1,256 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

conversion from '...' to non-scalar type '...' requested

Hi @all,

My small example does not compile... I know, that this (as always) has
reasons, but I want to know WHY?

BTW:
I only get errors with g++ (4.x), BCB (6.0),...
VS C++ (2005) works perfectly (without warnings etc.)

class classValue
{
public:
classValue() {}
};

class classHolder
{
public: classHolder(classValue &ami) {} // <== I know, but in
this case reference MUST be non-const
};

classHolder getAHolder()
{
return classValue(); // <--- Error: conversion from
'classValue' to non-scalar type 'classHolder' requested
}
Using a little trick, everthing works well...

class classValue
{
public:
classValue() {}
classValue &self() { return *this; }
};

class classHolder
{
public: classHolder(classValue &ami) {}
};

classHolder getAHolder()
{ return classValue().self();}

But why must I use this nasty indirection?
How is this phenomenon called?
Any other suggestions?

THX,
Kirsten

Jun 5 '06 #1
11 29919
tt******@gmx.de wrote:
My small example does not compile... I know, that this (as always) has
reasons, but I want to know WHY?
Because it's prohibited by the Standard.
BTW:
I only get errors with g++ (4.x), BCB (6.0),...
VS C++ (2005) works perfectly (without warnings etc.)
Make sure you disable "language extensions" when compiling with VC++.
class classValue
{
public:
classValue() {}
};

class classHolder
{
public: classHolder(classValue &ami) {} // <== I know, but in
this case reference MUST be non-const
};

classHolder getAHolder()
{
return classValue(); // <--- Error: conversion from
'classValue' to non-scalar type 'classHolder' requested
That's correct. A temporary cannot be bound to a non-const reference.
}
Using a little trick, everthing works well...

class classValue
{
public:
classValue() {}
classValue &self() { return *this; }
};

class classHolder
{
public: classHolder(classValue &ami) {}
};

classHolder getAHolder()
{ return classValue().self();}

But why must I use this nasty indirection?
It's a very bad idea to actually use it.
How is this phenomenon called?
Which one? Playing dirty tricks?
Any other suggestions?


Redesign.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 5 '06 #2
tthun...@gmx.de wrote:
Hi @all,

My small example does not compile... I know, that this (as always) has
reasons, but I want to know WHY?

BTW:
I only get errors with g++ (4.x), BCB (6.0),...
VS C++ (2005) works perfectly (without warnings etc.)
VS *builds* perfectly. I doubt it would actually work in practice
except by pure chance.

class classValue
{
public:
classValue() {}
};

class classHolder
{
public: classHolder(classValue &ami) {} // <== I know, but in
this case reference MUST be non-const
};

classHolder getAHolder()
{
return classValue(); // <--- Error: conversion from
'classValue' to non-scalar type 'classHolder' requested
}
You are returning type classHolder, so the return value you specify (a
*temporary* of type classValue) must be converted to a classHolder via
the constructor you supply. However, according to the C++ Standard,
non-const references cannot bind to temporaries, and that is a good
thing and for your protection.
Using a little trick, everthing works well...

class classValue
{
public:
classValue() {}
classValue &self() { return *this; }
};

class classHolder
{
public: classHolder(classValue &ami) {}
};

classHolder getAHolder()
{ return classValue().self();}

But why must I use this nasty indirection?
How is this phenomenon called?
Any other suggestions?


You are fighting against the rules of the language here, and this
trickery won't actually get you anywhere since you'll likely end up
with a dangling reference in your real code. Either don't use a
temporary or don't pass a non-const reference to
classHolder::classHolder() -- that is, either make a copy of the
classValue object or pass a const reference to it.

Cheers! --M

Jun 5 '06 #3
tt******@gmx.de wrote:
Hi @all,

My small example does not compile... I know, that this (as always) has
reasons, but I want to know WHY?
Because you cannot bound an rvalue to a non-const reference.
BTW:
I only get errors with g++ (4.x), BCB (6.0),...
VS C++ (2005) works perfectly (without warnings etc.)

class classValue
{
public:
classValue() {}
};

class classHolder
{
public: classHolder(classValue &ami) {} // <== I know, but in
this case reference MUST be non-const
};

classHolder getAHolder()
{
return classValue(); // <--- Error: conversion from
'classValue' to non-scalar type 'classHolder' requested
If you could do that, you'd get several more important problems:

void f(int& i)
{
i = 2;
}

int main()
{
int i = 4;
double d = 1.0;

f(i); // ok
f(d); // ok??
f(4); // ouch!

// what should this output?
std::cout << d;
}

For the second call to f(), the double gets converted to a temporary
int (an rvalue), which gets modified in f(). Do you expect 'd' to get
modified also? It won't and that's misleading, dangerous and illegal.
}

Using a little trick, everthing works well...
Yes, you may do that.
class classValue
{
public:
classValue() {}
classValue &self() { return *this; }
};

class classHolder
{
public: classHolder(classValue &ami) {}
};

classHolder getAHolder()
{ return classValue().self();}

But why must I use this nasty indirection?


Because that's how the language is defined. Note that you may also do

classholder getAHolder()
{
classValue v;
return classHolder(v);
}
Jonathan

Jun 5 '06 #4
Yes, hate me... I believe your explanations, of course!!!!
But sometimes you NEED to be nasty.

I explain why I cannot use const...

class classHolder
{
public: classHolder(classValue &ami) {}
};

class classHolder_const : public classHolder
{
public: classHolder(const classValue &ami) {}
};

classValue aValue;
const classValue aConstValue;
classHolder aHolder1 = aValue; // <= ok
classHolder aHolder2 = aConstValue; // <= forbidden
classHolder_const aHolder3 = aValue; // <= ok
classHolder_const aHolder4 = aConstValue; // <= ok

My classHolder may NOT get any const variables.

Jun 5 '06 #5
tt******@gmx.de wrote:
Yes, hate me... I believe your explanations, of course!!!!
But sometimes you NEED to be nasty.
When getting personal, like you are doing here, you need to include
at least the name of whom you reply to. Otherwise the entire forum
thinks you're calling them nasty (did you know that plural and singular
form for the second person in English are both "you"?)

I don't mind being called nasty myself, I don't don't like to fall
under a blanket occusation.
I explain why I cannot use const...

class classHolder
{
public: classHolder(classValue &ami) {}
};

class classHolder_const : public classHolder
{
public: classHolder(const classValue &ami) {}
};

classValue aValue;
const classValue aConstValue;
classHolder aHolder1 = aValue; // <= ok
classHolder aHolder2 = aConstValue; // <= forbidden
classHolder_const aHolder3 = aValue; // <= ok
classHolder_const aHolder4 = aConstValue; // <= ok

My classHolder may NOT get any const variables.


That's all fine and dandy. But if you're stuck with a certain
format of your constructors, then you have to be careful with the
return statements. You simply cannot use 'classValue()' syntax
where an instance of 'classHolder' is expected. That's all.
If you need to allow default-initialisation of 'classHolder',
just give it a default constructor. Otherwise, rethink what your
classes do and/or how they do it.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 5 '06 #6
tt******@gmx.de wrote:
Yes, hate me...
Don't be so hard on yourself. You've done nothing worthy of such scorn
and derision... yet (you don't put your open brace on the same line as
the for statement, do you?).
But sometimes you NEED to be nasty.
But if you do need to be nasty, you had better know what the
implications of your nastiness are. It appears to me that you don't.
I explain why I cannot use const...

class classHolder
{
public: classHolder(classValue &ami) {}
};

class classHolder_const : public classHolder
{
public: classHolder(const classValue &ami) {}
};

classValue aValue;
const classValue aConstValue;
classHolder aHolder1 = aValue; // <= ok
classHolder aHolder2 = aConstValue; // <= forbidden
classHolder_const aHolder3 = aValue; // <= ok
classHolder_const aHolder4 = aConstValue; // <= ok

My classHolder may NOT get any const variables.


That doesn't really explain much of anything. How are you using that
non-const reference? That's the real question here since fighting
against the rules of the language like this will likely bite you in the
end when you find you have a dangling reference. To reiterate: either
don't use a temporary or don't pass a non-const reference to
classHolder::classHolder() -- that is, either make a copy of the
classValue object or pass a const reference to it.

Cheers! --M

Jun 5 '06 #7
H

Victor Bazarov schrieb:
tt******@gmx.de wrote:
Yes, hate me... I believe your explanations, of course!!!!
But sometimes you NEED to be nasty.
When getting personal, like you are doing here, you need to include
at least the name of whom you reply to. Otherwise the entire forum
thinks you're calling them nasty (did you know that plural and singular
form for the second person in English are both "you"?)


I am really sorry!!! Big misunderstanding.
First, it was not meant personal.
Second, it was generally spoken (doing nasty C++ tricks)

And "hate me" was meant funny... because when asking question you
always get the answer: not standard => redesign
I often do things, which are not the "standard" way. Yes, I fight
against the language! But only for creating a framework, which can be
used the "standard" way.
BTW... Many design patterns use a way which is not the "standard" way.
That's all fine and dandy. But if you're stuck with a certain
format of your constructors, then you have to be careful with the
return statements. You simply cannot use 'classValue()' syntax
where an instance of 'classHolder' is expected. That's all.
If you need to allow default-initialisation of 'classHolder',
just give it a default constructor. Otherwise, rethink what your
classes do and/or how they do it.


classHolder getAHolder()
{ return classHolder (classValue());}

This compiles...
Is this ok?
Nasty trick again?
Why can't the compiler DO this itself? No you must throw an error...

Jun 5 '06 #8
> > I explain why I cannot use const...

class classHolder
{
public: classHolder(classValue &ami) {}
};

class classHolder_const : public classHolder
{
public: classHolder(const classValue &ami) {}
};

classValue aValue;
const classValue aConstValue;
classHolder aHolder1 = aValue; // <= ok
classHolder aHolder2 = aConstValue; // <= forbidden
classHolder_const aHolder3 = aValue; // <= ok
classHolder_const aHolder4 = aConstValue; // <= ok

My classHolder may NOT get any const variables.


That doesn't really explain much of anything. How are you using that
non-const reference? That's the real question here since fighting
against the rules of the language like this will likely bite you in the
end when you find you have a dangling reference. To reiterate: either
don't use a temporary or don't pass a non-const reference to
classHolder::classHolder() -- that is, either make a copy of the
classValue object or pass a const reference to it.


It just explained, why I cannot use const references...
But to answer your question... in my "real code" (I constructed this..
names and everthing) the constructors are all "copy constructors". So I
copy all values without modifying anything or use references later.

Yes, therefore I could use const references, but I want to forbid the
usage of "const instances" with classHolder, but not with
classHolder_const...

Jun 5 '06 #9
tt******@gmx.de wrote:
That doesn't really explain much of anything. How are you using that
non-const reference? That's the real question here since fighting
against the rules of the language like this will likely bite you in the
end when you find you have a dangling reference. To reiterate: either
don't use a temporary or don't pass a non-const reference to
classHolder::classHolder() -- that is, either make a copy of the
classValue object or pass a const reference to it.


It just explained, why I cannot use const references...
But to answer your question... in my "real code" (I constructed this..
names and everthing) the constructors are all "copy constructors". So I
copy all values without modifying anything or use references later.

Yes, therefore I could use const references, but I want to forbid the
usage of "const instances" with classHolder, but not with
classHolder_const...


Finally we get down to it. Tell us more (and show us more code) about
why and how you want to do this, and then perhaps we can tell you the
best way to accomplish what you want to do.

Cheers! --M

Jun 5 '06 #10
tt******@gmx.de wrote:
[...]
classHolder getAHolder()
{ return classHolder (classValue());}

This compiles...
It does???
Is this ok?
No, certainly not.
Nasty trick again?
Or a compiler bug... Or operator error...
Why can't the compiler DO this itself? No you must throw an error...


Are you sure you're using the right compiler?

----------------------------
struct A {};
struct B { B(A&) {} };
B foo() {
return B(A());
}
----------------------------
Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !

Your Comeau C/C++ test results are as follows:

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 4: error: no instance of constructor "B::B" matches the
argument list
The argument types that you used are: (A)
return B(A());
^

1 error detected in the compilation of "ComeauTest.c".

In strict mode, with -tused, Compile failed
Hit the Back Button to review your code and compile options.
----------------------------

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 5 '06 #11

mlimber schrieb:

Finally we get down to it. Tell us more (and show us more code) about
why and how you want to do this, and then perhaps we can tell you the
best way to accomplish what you want to do.

Cheers! --M


I can only tell you more... copying code would not be possible...

think about two classes

template<typename T>
property<T>

template<typename T>
property_link<T> : public property_link_any

-----

property<T> contains values, and property_link<T> is only a "link" to a
property<T> (contains a pointer, of course).
BTW: property_link_any can link to ANY property<T>. Of course in the
real code, there are lots of compatibility checks...

Now I am linking...

property<T> myProp
const property_link<T> myLink = myProp;

ok!

using a constant version of property_link<T> I can only use
const-member-functions of property<T>. Perfect! But I can do nasty
things now...

property_link<OtherT> myOtherLink = myLink;

A kind of copy constructor is called, and myOtherLink links to the same
thing as myLink... Now imagine you COULD (just imagine... makes my
explanation easier) access T via OtherT => nothing is const now!

Therefore:
property_link<T>::property_link(property_link_any &) <= does not allow
the example
const_property_link<T>::const_property_link(const property_link_any &)
<= I want to force the usage of this class instead.

In my short example I have not mentioned the default constructor and
detailed stuff... but forget this for one moment, please... I have
managed those details already.

Jun 5 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Tumurbaatar S. | last post by:
Hi, I'm running MySQL 3.23.55 on WinXP and have some problem using non latin charset. I've added these 2 lines under group of my.ini: character-sets-dir = c:/mysql/share/charsets/...
6
by: Thomas Barth | last post by:
Hi, I'm new to windows programming and still reading a book about windows-programming with C++. I copied the following code from the book into my ide (Eclipse/CDT) to comprehend the code, but two...
7
by: Michael Lehn | last post by:
Hi, I have a question regarding the conversion of objects. When is the conversion done by the constructor and when by the operator. My feeling tells me that the constructor is preferred. But...
31
by: Bjørn Augestad | last post by:
Below is a program which converts a double to an integer in two different ways, giving me two different values for the int. The basic expression is 1.0 / (1.0 * 365.0) which should be 365, but one...
14
by: junky_fellow | last post by:
Can anybody please explain this: When a value with integer type is converted to another integer type other than _Bool, if the new type is unsigned, the value is converted by repeatedly...
3
by: gilad | last post by:
This is to announce the beta 2 release of Aumplib. After garnering comments from this newsgroup, I have modified the code to use a more standard style convention. Aumplib is a C# namespace which...
4
by: Påhl Melin | last post by:
I have some problems using conversion operators in C++/CLI. In my project I have two ref class:es Signal and SignalMask and I have an conversion function in Signal to convert Signal:s to...
28
by: James Brown | last post by:
All, I have a series of characters which I need to convert to integer values. Each character is read in turn from a function 'nextch', and hex-digits are identified by the isxdigit function - so...
2
by: =?Utf-8?B?U2FtZWVrc2hh?= | last post by:
Suppose there are 2 classes A and B with a int parameter called 'val' in each. Both of them provide a public constructor with int type parameter. Suppose class A provides a explicit conversion...
2
by: xtrigger303 | last post by:
Hi to all, I was reading Mr. Alexandrescu's mojo article and I've a hard time understanding the following. Let's suppose I have: //code struct A {}; struct B : A {};
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.