473,895 Members | 2,419 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

explicit conversion

Hi,

This is a question about whether I am right that a particular syntactic
sugar is missing in C++.

Let me explain with an example. Let us say I have a class for complex
numbers, and I want people to be able to initialize real numbers (like
an object of type double) from it ... in such a context (or if someone
explicitly casts to double), the imaginary part is to be ignored.
However, I certainly do not want people to be able to ask whether
Complex(1,2) > 0, or even whether Complex(1,0)>0, or pass a complex
number to a function expecting a real number. Of course, it is easy to
do that by forcing people to write definitions like `double x =
z.realpart();', but I am asking about letting people use the syntax
`double x(z)', or `double x = z'

If instead of double, I had a class Double, I could play convoluted
games with `explicit Double(Complex: :Double);' and Complex::Double an
otherwise unused class (possibly by naming it
IWillBreakYourB onesIfYouUseIt) to which class Complex can be converted.
But is it really not possible to do it if I want double instead of
Double. (The rule against multiple implicit user-defined conversions and
no constructors for non-class objects seems to defeat me. If only the
rule were against more than two rather than more than one ...)

More fundamentally, is there a reason (implementation difficulty,
difficulty of specification, neatness) because of which `explicit
operator' is not in the language? Constructors and conversions work
very similarly most of the time, so why this asymmetry?

Many thanks
Tanmoy

Jul 22 '05 #1
9 2386
Tanmoy Bhattacharya wrote:
Hi,
Hey, it's been a while, hasn't it? Welcome back!
This is a question about whether I am right that a particular syntactic
sugar is missing in C++.
[...]
More fundamentally, is there a reason (implementation difficulty,
difficulty of specification, neatness) because of which `explicit
operator' is not in the language? Constructors and conversions work
very similarly most of the time, so why this asymmetry?


Actually, I recall recently seeing some discussion about this in either
comp.lang.c++.m oderated or in comp.std.c++ (or both). I think the answer
to this is that it's not going to help you, IIUIC.

You specifically don't want

Complex a(1,2);
if (a > 0) ...

to be legal but you do want

Complex a(1,2);
double r(a);

to be legal. But there is no difference between the two. 'a' is either
going to be converted to 'double' when a 'double' is expected or not.

If you provide a conversion operator, making it explicit will force you
to write, e.g.,

Complex a(1,2);
double r(double(a));

but you already have that ability by calling '.realpart()'.

Making constructors explicit forces somebody to write 'Type(arg)' instead
of letting the compiler figure out that 'Type' should be constructed from
the 'arg'. So, making 'Type::operator Type2()' to be explicit does not
miraculously allow _some_ conversions while disallowing other.

That's my take on it, anyway.

V
Jul 22 '05 #2
Victor Bazarov <v.********@com Acast.net> wrote in message news:<oy******* *********@newsr ead1.dllstx09.u s.to.verio.net> ...
(Parts snipped without indication)
Hey, it's been a while, hasn't it? Welcome back!
Yeah ... got a bit too busy with things.
You specifically don't want

Complex a(1,2);
if (a > 0) ...

to be legal but you do want

Complex a(1,2);
double r(a);

to be legal. But there is no difference between the two. 'a' is either
going to be converted to 'double' when a 'double' is expected or not.
Correct.
Making constructors explicit forces somebody to write 'Type(arg)' instead
of letting the compiler figure out that 'Type' should be constructed from
the 'arg'.
And allows you to write Type x(arg), though not Type x = arg.
So, making 'Type::operator Type2()' to be explicit does not
miraculously allow _some_ conversions while disallowing other.


The semantics I desire is for explicit Type::operator Type2() (or
explicit operator ::Type2(Type) if such were to be allowed instead) to
behave identically to explicit Type2::Type2(Ty pe).

Thanks (and thanks for the hint of previous discussion... I googled
some from 1996 as well!)
Tanmoy
Jul 22 '05 #3
"তন্ময়
ভট্টাচার্য ্য"
<ta****@mindspr ing.com> wrote...
Victor Bazarov <v.********@com Acast.net> wrote in message
news:<oy******* *********@newsr ead1.dllstx09.u s.to.verio.net> ...
(Parts snipped without indication)
[...]
Making constructors explicit forces somebody to write 'Type(arg)' instead
of letting the compiler figure out that 'Type' should be constructed from
the 'arg'.


And allows you to write Type x(arg), though not Type x = arg.


Right.
So, making 'Type::operator Type2()' to be explicit does not
miraculously allow _some_ conversions while disallowing other.


The semantics I desire is for explicit Type::operator Type2() (or
explicit operator ::Type2(Type) if such were to be allowed instead) to
behave identically to explicit Type2::Type2(Ty pe).

I am not sure I follow. This is how it is now:

struct Type {};
struct Type2 {
explicit Type2(Type);
};

Type arg;
Type2 x(arg);
Type2 y = arg; // error -- no conversion exists

So, now replacing the constructor in Type2 with the cast in Type

struct Type2 {};
struct Type {
explicit operator Type2();
};

should allow

Type arg;
Type2 x(arg); // OK
Type2 y = arg; // error

, right? What I don't understand is how the conversion operator's being
explicit would affect the construction of Type2. Essentially, the two
forms

Type2 x(arg);

and

Type2 y = arg;

are using the same constructor, Type2(Type2 const&), provided by the
compiler, where the reference is bound to a temporary object created from
'arg'. There is no other constructor to use, is there? So, they both
are like

Type2 const& rtemp(arg.opera tor Type2());
Type2 z(rtemp);

and if we forego the creation of the temporary (as allowed), they both
are equivalent to

Type2 z(arg.operator Type2());

How are you going to make the compiler distinguish between 'Type2 x(arg)'
and 'Type2 x = arg', when the [other part of the ] language says that they
are the same? Conclusion: introduction of 'explicit' type conversion ops
will require other fundamental changes to the language, which will most
likely affect _tons_ of existing programs. Besides, it's unclear that such
change _can_ be done.

..Shrug.

I hope you find plenty of more logical explanations in the other threads
on Google.

Victor
Jul 22 '05 #4
Victor Bazarov wrote:
How are you going to make the compiler distinguish between 'Type2 x(arg)' and 'Type2 x = arg', when the [other part of the ] language says that they are the same? Conclusion: introduction of 'explicit' type conversion ops will require other fundamental changes to the language, which will most likely affect _tons_ of existing programs. Besides, it's unclear that such change _can_ be done.


Thanks for your analysis. I, however, have difficulty following your
argument in detail. It is not quite correct that Type2 x(arg) and
Type2 x=arg are identical: the former calls the explicit constructor
for Type2::Type2(Ty pe) if it exists, whereas the latter cannot call
that. In other words, yes, both are supposed to call
Type2::Type2(Ty pe) if it exists, but the difference is whether an
explicit Type2::Type2(Ty pe) participates in the resolution.

Similarly, it would be nice if when Type2::Type2(Ty pe) did not exist
(to avoid ambiguity), but an `explicit' version of Type::operator
Type2() existed, it would participate in resolution only in the former,
and not the latter, case. Again, though in both cases the copy
constructor is invoked as Type2::Type2(ar g.Type::operato r Type2()), the
question is only whether declarations of Type::operator Type2 that are
marked `explicit' should participate.

Note that the compiler is supposed to known the semantics of the
(impicit) copy constructor, and it is typically elided in this case, so
it is difficult to argue that it is a hardship to remember the direct
initialization context in this case.

I do not see how this affects any existing code that is correct. An
example would help. I am not suggesting that something other than the
copy constructor be used, nor that something other than the conversion
operator be used: only suppress the use of the conversion under certain
conditions.

But maybe given the extensive discussion of the whole issue in
comp.std.c++ in 1996, still available on google, we should take the
discussion off-line. Incidentally, that discussion was mainly
concerned with using static_cast<dou ble>, with which you probably would
have no quarrel, rather than direct initialization of double, though
this was briefly mentioned as well.

Tanmoy

Jul 22 '05 #5
<ta****@mindspr ing.com> wrote...
[...]
I do not see how this affects any existing code that is correct. An
example would help. I am not suggesting that something other than the
copy constructor be used, nor that something other than the conversion
operator be used: only suppress the use of the conversion under certain
conditions.
You'd need to state those conditions. I presented this example:

class Type2 {};
class Type {
operator Type2();
};

Type arg;
Type2 x(arg); // 1
Type2 x = arg; // 2

Explain what certain conditions apply here to allow suppression of
Type::operator Type2 used in the case (2), if you think this might
be beneficial.
But maybe given the extensive discussion of the whole issue in
comp.std.c++ in 1996, still available on google, we should take the
discussion off-line. Incidentally, that discussion was mainly
concerned with using static_cast<dou ble>, with which you probably would
have no quarrel, rather than direct initialization of double, though
this was briefly mentioned as well.


Well, I'd have to study the 1996 discussion to be able to participate
in any even off-line conversation (if you'd like to continue). I only
have one comment: it seems that you yourself noted that it would really
be a true syntactic sugar (given it's possible to implement), and it's
not like a serious problem that can be solved by making operators
explicit has been overlooked. Perhaps the absence of the real need
is what holds the introduction back...

V
Jul 22 '05 #6
"Victor Bazarov" <v.********@com Acast.net> wrote in message news:<FKBkd.274 07$5K2.6721@att bi_s03>...
You'd need to state those conditions. I presented this example:

class Type2 {};
class Type {
operator Type2();
};

Type arg;
Type2 x(arg); // 1
Type2 x = arg; // 2

Explain what certain conditions apply here to allow suppression of
Type::operator Type2 used in the case (2), if you think this might
be beneficial.
I thought I did exactly that in my previous post: the proposed rule
would be that a Type::operator Type2() declared as explicit will be
used only in two cases: (1) when Type appears as the only parameter of
an explicit constructor or direct initialization, and (2) when a
static or C-style cast operator is used. In the first of these, the
copy constructor of Type2 must be accessible, though it can be elided.
It is specifically not used when the conversions called for are
implicit *and* are not being used in a direct initialization. Note
that // 2 in your code is an initialization, but not direct
initialization, but // 1 is.

To complete the symmetry, one could also have that an explicit
constructor be useable in (2) in this paragraph. (i.e. Not only
Type2(Type), but also (Type2)Type would be able to use an explicit
constuctor for Type2): this is, however, a change which might
theoretically affect some programs, though I doubt
it occurs too often.

It turns out that the second of the two is more important, especially
for templates. The idea is that if I have a function which works on
say the string representation of its parameter, it is tempting to
write `template <T> f(T x) { String y(x); /* use y */}' or that String
y(x) bit is written as `String y = static_cast<Str ing>(x)'. Note that
this avoids namespace pollution: the template writer does not force a
particular name like toString which must appear for people to be using
the template: it must only support the initialization or the static
cast. And, in fact, this is precisely where explicit constructors are
useful: an explicit constructor for String(T) is all that is needed to
make this work. Unfortunately, this needs access to the String class
definition, which users should not necessarily have; and, moreover, it
is impossible if a non-class type like double is substituted for
string in this example.

The point is that the need for `explicit' in the constructor is
orthogonal to the access requirements to the internals of the class,
and even to the interface of the class. Ergo, `explicit', if it
exists, should not need a change to the class definition as it
currently does.
Well, I'd have to study the 1996 discussion to be able to participate
in any even off-line conversation (if you'd like to continue). I only
have one comment: it seems that you yourself noted that it would really
be a true syntactic sugar (given it's possible to implement), and it's
not like a serious problem that can be solved by making operators
explicit has been overlooked. Perhaps the absence of the real need
is what holds the introduction back...


It was a nice discussion a long time back. It turns out that, as
explained variously and repeatedly on the thread, the original
proposal was to have both explicit constructors and explicit
conversion operators, though I did not find the originally intended
semantics mentioned on the thread (it certainly would have allowed the
static cast<Type2>, and disallowed calling a non-constructor function
with parameter Type2). This was the intent of the proposer, as well
as some of the committee members. The actual text of the proposal,
however, did not mention the operators, and that is how some else
interpreted it. The difference came to light only after the standard
became pretty final, and it was not considered worth changing it.

So, you are right that the `absence of the real need is what holds the
introduction back', but there does exist, and did exist, a perceived
need all along.

In any case, thanks for pointing me to the discussion. And, now I
will go back to my slumber till I learn how to google well.

Tanmoy
Jul 22 '05 #7
ta****@mindspri ng.com (তন্ময় ভট্টাচার্য ্য) wrote in message news:<61******* *************** ***@posting.goo gle.com>...
[content snipped]

But, seriously dude. Why would you copy/paste your handle from a
Microsoft product? Did you need to spell check it?

Anyway, in order to avoid that cruft, you do the following if you
*must* edit in Word or whatever. Copy/paste it into notepad first.
That will cause all the "mystery" formatting to be dropped in
favour of plain old ASCII text. Then copy it to your news reader.
Socks
Jul 22 '05 #8
pu*********@hot mail.com wrote:
ta****@mindspri ng.com (তন্ময় ভট্টাচার্য ্য) wrote in message news:<61******* *************** ***@posting.goo gle.com>...
[content snipped]

But, seriously dude. Why would you copy/paste your handle from a
Microsoft product? Did you need to spell check it?

Anyway, in order to avoid that cruft, you do the following if you
*must* edit in Word or whatever. Copy/paste it into notepad first.
That will cause all the "mystery" formatting to be dropped in
favour of plain old ASCII text. Then copy it to your news reader.


There is no ASCII text in whatever lies between the parentheses.
It's Bengali. And it's in Netscape's version of UNICODE, I guess.

V
Jul 22 '05 #9
pu*********@hot mail.com wrote in message news:<c7******* *************** ****@posting.go ogle.com>...
ta****@mindspri ng.com (তন্ময় ভট্টাচার্য ্য) wrote in message news:<61******* *************** ***@posting.goo gle.com>...

confusing my name with microsoft formatting. At least noone thought
it was an APL program!

Seriously, news and web are two different media, and even Google
should have known that. It used html entities to represent unicode
characters, instead of mime-encoding in utf-8 or something. After
this post, I promise to spelll my name in a more conventional fashion.

Thanks for pointing it out to me
Tanmoy
Jul 22 '05 #10

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

Similar topics

1
5662
by: Stub | last post by:
Docs says that "The compiler does not use an explicit constructor to implement an implied conversion of types. It's purpose is reserved explicitly for construction." I put up code of three cases at the bottom. Hope you can help me understand the "explicit" keyword and its usage. Specifically, Is "explicit" keyword only associated with constructor in C++? What's "implied conversion of types"?
2
2150
by: Dave | last post by:
Hello NG, Can anybody fathom the purpose of an explicit copy constructor? On page 232 of the Josuttis STL reference, I see a reference to such. How could you ever need to supress the possibility of an implicit conversion from type T to type T? Such an implicit conversion could never occur because you're already of the required type! Thanks,
3
2114
by: spamadress | last post by:
Hello I wonder why only constructors can be qualified with explicit to prevent implicit conversion, but not conversion operators. To me the following makes perfectly sense: struct A { explicit operator int() { return 0;} ; }; void foo(int) {};
4
2672
by: Ken Tough | last post by:
Seems like a simple thing to find out, but I'm struggling. I have googled, but everything I find is about implicit conversion, not explicit. Is this implementation-specific, or does ANSI/ISO lay out what should happen for: -------------------------- signed char sc; unsigned char uc;
2
6879
by: Alex Sedow | last post by:
Why explicit conversion from SomeType* to IntPtr is not ambiguous (according to standart)? Example: // System.IntPtr class IntPtr { public static explicit System.IntPtr (int); public static explicit System.IntPtr (long);
31
3644
by: Michael C | last post by:
If a class inherits from another class, say Form inherits from control, then I can assign the Form to a variable of type Control without needing an explicit conversion, eg Form1 f = new Form1(); Control c = f; An enum value inherits from int but it doesn't get implicitly converted: HorizontalAlignment h = HorizontalAlignment.Center;
1
2332
by: petschy | last post by:
hello, i've run into an error when qualifying a copy ctor 'explicit'. the strange thing is that i get a compiler error only if the class is a template and declare the variable as X<Zx = y. X<Zx(y) is fine. Tested with gcc 2.95, 3.3, 4.1, all gave the same error: t.cpp: In function 'int main()': t.cpp:44: error: no matching function for call to 'D<int>::D(D<int>&)'
42
2728
by: coder_lol | last post by:
Thanks everyone again for contributing to helping me clear C++ confusions. I did some serious reading on copy constructors and assignments and I think I've got a good handle on the memory stuff. Well, I came across Scott Meyer's SmartPtr example from some 10 years ago. I like the template member function for type conversion to solve inheritance issues. On MSVS 2003, I get the below error, if I declare the constructor SmartPtr(T*...
12
7235
by: Rahul | last post by:
Hi Everyone, I have the following code and i'm able to invoke the destructor explicitly but not the constructor. and i get a compile time error when i invoke the constructor, why is this so? class Trial { public: Trial() {
0
9836
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 synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10847
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 captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10937
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 most users, this new feature is actually very convenient. If you want to control the update process,...
0
9651
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 launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
8028
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7179
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5865
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 the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
4288
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3298
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 effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.