473,574 Members | 2,309 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(cla ssValue &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(cla ssValue &ami) {}
};

classHolder getAHolder()
{ return classValue().se lf();}

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

THX,
Kirsten

Jun 5 '06 #1
11 29952
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(cla ssValue &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(cla ssValue &ami) {}
};

classHolder getAHolder()
{ return classValue().se lf();}

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(cla ssValue &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(cla ssValue &ami) {}
};

classHolder getAHolder()
{ return classValue().se lf();}

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::cl assHolder() -- 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(cla ssValue &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(cla ssValue &ami) {}
};

classHolder getAHolder()
{ return classValue().se lf();}

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(cla ssValue &ami) {}
};

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

classValue aValue;
const classValue aConstValue;
classHolder aHolder1 = aValue; // <= ok
classHolder aHolder2 = aConstValue; // <= forbidden
classHolder_con st aHolder3 = aValue; // <= ok
classHolder_con st 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(cla ssValue &ami) {}
};

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

classValue aValue;
const classValue aConstValue;
classHolder aHolder1 = aValue; // <= ok
classHolder aHolder2 = aConstValue; // <= forbidden
classHolder_con st aHolder3 = aValue; // <= ok
classHolder_con st 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(cla ssValue &ami) {}
};

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

classValue aValue;
const classValue aConstValue;
classHolder aHolder1 = aValue; // <= ok
classHolder aHolder2 = aConstValue; // <= forbidden
classHolder_con st aHolder3 = aValue; // <= ok
classHolder_con st 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::cl assHolder() -- 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 misunderstandin g.
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(cla ssValue &ami) {}
};

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

classValue aValue;
const classValue aConstValue;
classHolder aHolder1 = aValue; // <= ok
classHolder aHolder2 = aConstValue; // <= forbidden
classHolder_con st aHolder3 = aValue; // <= ok
classHolder_con st 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::cl assHolder() -- 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_con st...

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::cl assHolder() -- 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_con st...


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

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

Similar topics

0
2254
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/ default-character-set=cp1251 Then restarted server and created a simple database
6
4365
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 errors occur. In function `LRESULT WndProc(HWND__*, unsigned int, unsigned int, long int)': line 48: error: invalid conversion from `void*' to...
7
3255
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 I couldn't find the exact rule in the C++ standard. And what if the classes have template parameters? It would be great if somebody could get...
31
6594
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 variable becomes 364 and the other one becomes 365. Does anyone have any insight to what the problem is? Thanks in advance. Bjørn
14
9311
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 adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
3
8781
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 is made up of a set of classes that interface several prominent open source audio conversion projects via DLL and P/Invoke: LAME (MP3 encoding),...
4
2901
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 SignalMask:s. The reason is I have a free function called WaitSignal that accepts av SignalMask where Signals parameters are supposed to implicitly be...
28
3389
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 I'm looking at '0' - '9', 'A' - 'Z' and 'a' - 'z'. Here is what I've got: int num = 0;
2
2518
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 operator taking B object as a parameter and returning an A object. A objA = new A(10); B objB = new B(5); objA = (A)objB; --call public static...
2
1859
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
7801
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7719
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8044
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8229
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7808
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
6450
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
3739
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3749
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1055
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.