22843

Conversion operator vs constructor from given type. Which is preferable?

I'm defining iterator types for my container and of course I want iterator to be convertible to const_iterator. But I'm not sure which is better/preferable:

Conversion operator in iterator

class iterator { operator const_iterator(); };

or non-explicit constructor in const_iterator

class iterator { // implementation friend class iterator; // hard to avoid this }; class const_iterator { const_iterator(iterator const &); };

Are there any guidelines which way is better?

Answer1:

You should write a casting operator only if it is possible to return the desired type without constructing a new object, or if its return is a simple data type. For example, if it were to return a const reference to a property within the class, then you should write it as a casting operator.

In all other cases, you should just write the appropriate constructor.

Answer2:

As a general rule:

There is almost <strong>never</strong> a good reason to provide <strong>implicit conversion operators</strong>; it is always <strong>preferable</strong> to use <strong>conversion constructors</strong>. With implicit conversion operators you will seldom find them invoked when you don't expect and create unnecessary confusions.

<strong>conversion constructors</strong> is also a better way since it lets you adheres you to the <strong>Principle of least Astonishment.</strong>

The only common exception to this rule is provide a conversion to a boolean type, so that objects (e.g., smart pointers) can be used in boolean contexts.

Answer3:

Some implementations let iterator inherit from const_iterator, and get the conversion for free.

Recommend

  • Multiple Dispatch with Generics
  • OpenCV imread with foreign characters
  • Android text field: distance between line and text
  • ube error: _mm_aeskeygenassist_si128 intrinsic requires at least -xarch=aes
  • Does Windows Phone 7 have a standard Edit/Add/Delete convention?
  • Cast uint -> double invalid?
  • How to access meteor package name inside package?
  • How to set elevation color?
  • How to get latest version of a artifact on Bintray using JSONP
  • Tell Git to stop prompting me for conflicts when none really exist?
  • Invalid Date on validation Date of js
  • C++ pointer value changes with static_cast
  • Unable to install Git-core+svn by MacPorts
  • how to avoid repetitive constructor in children
  • C: Incompatible pointer type initializing
  • Django simple Captcha “No module named fields” error
  • How to get Eclipse Oxygen to run on Java 9
  • Could not find rake using whenever rails
  • Control modification in presentation layer
  • Email format validation in mvc3 view
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • AES padding and writing the ciphertext to a disk file
  • VS2008 Enable C++ Exception with SEH
  • How to add date and time under each post in guestbook in google app engine
  • Rearranging Cells in UITableView Bug & Saving Changes
  • Circular dependency while pushing http interceptor
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • Linker errors when using intrinsic function via function pointer
  • trying to dynamically update Highchart column chart but series undefined
  • coudnt use logback because of log4j
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • embed rChart in Markdown
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • Django query for large number of relationships
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • Unable to use reactive element in my shiny app
  • How to push additional view controllers onto NavigationController but keep the TabBar?
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize