C++ trick: selectively restrict implicit conversions

TL;DR: given a class Foo with an implicit constructor from int, how to allow the implicit conversion in f(42); but not in g(42); where both f and g take a Foo const & argument?

Background

So I have this real class that performs numeric operations that I want use just like any other C++ numeric type. For instance, I can write the following:

float f = 15, g = 3.5;
int x = f / g;

If I decide that I need double precision, I can write:

double f = 15, g = 3.5;
int x = f / g;

And of course, using my real class for even higher precision:

real f = 15, g = 3.5;
int x = f / g;

I like that. I can just write code as usual, and when I need higher precision, I use real instead of double. It's transparent and convenient.

Implementation example

Here is a highly simplified example of a real class:

struct real
{
    inline real(double d) : m_value(d) {}
    inline operator int() const { return (int)m_value; }
    /* ... */
    long double m_value;
};

It is possible to write real f = 15 because of the implicit constructor. Actually, C++ constructors are always implicit unless specified otherwise.

It is possible to write int x = f / g because of the conversion operator.

So far, so good.

The problem with implicit promotion

Here is how fabs could be implemented:

real fabs(real const &r)
{
    return real(r.m_value < 0 ? -r.m_value : r.m_value);
}

But now we have a problem. A subtle problem. Consider the following code:

double x = fabs(-5.0);

What does this do? Well, it depends. It depends whether <cmath> was included or not. Because if <cmath> wasn’t included, then that code is going to automatically promote -5.0 to a real and call our custom function instead of the one provided by the math library! With no compile-time warning!

This is confusing. It should not happen. But it is a well known problem and there are several obvious workarounds:

  1. What most professional C++ programmers will tell you: use namespaces
  2. Mark the real(int) constructor explicit

The problem with 1. is that I am not a professional C++ programmer. I am a C programmer who uses C++. I use preprocessor macros and printf and memalign and goto. Try and stop me!

The problem with 2. is that I can no longer write real f = 15, I would need real f(15) or real f = real(15) instead. This is not acceptable, I want real to behave exactly like float and others, to the fullest extent of what the language allows.

Another solution

Fortunately, the C++ standard has a solution for us: “Implicit conversions will be performed [...] if the parameter type contains no template-parameters that participate in template argument deduction” (ISO/IEC 14882:1998, section 14.8.1.4). You cannot have implicit conversion and template argument deduction at the same time.

It means we just have to make fabs a template function! Which means making real a template class, too.

A quick way to fix real would be:

/* N is unused */
template<int N> struct real_base
{
    inline real_base(double d) : m_value(d) {}
    inline operator int() const { return (int)m_value; }
    /* ... */
    long double m_value;
};

typedef real_base<0> real;

The template argument is useless, unfortunately. It will just have to be here, forever. But who knows, you might find a use for it one day.

And to fix fabs:

/* A generic template declaration is needed */
template<int N> real_base<N> fabs(real_base<N> const &r);

/* Here we just add template<> to the previous version */
template<>
real fabs(real const &r)
{
    return real(r.m_value < 0 ? -r.m_value : r.m_value);
}

So, what happens with double x = fabs(-5.0); when we forget to include <cmath> now? Well, here is what GCC says:

In function ‘int main()’:
error: no matching function for call to ‘fabs(double)’
note: candidate is:
note: template<int N> real_base<N> fabs(const real_base<N>&)

It seems we’ve successfully managed to avoid the problematic implicit conversion, yet still allow it in places where it was useful!

So what is the rule? It’s simple: where implicit conversion should not be allowed, make the function a specialised template function.

  • Posted: 2012-02-08 22:14 (Updated: 2012-02-09 00:31)
  • Author: sam
  • Categories: code tip c++

Comments

158. MelbaJoulp -- 2017-01-13 07:10
159. MeghanCon -- 2017-01-13 20:47

get healthy life essay free example cover letters for resume gender discrimination in malaysia essay http://www.tukaerusite.com/j?u=http%3A%2F%2Fkayble.us

160. Angelavep -- 2017-01-13 22:16

You always do the right thing. God Bless you. Thank you

161. SusanArrix -- 2017-01-15 22:28

gcse maths statistics coursework help free restaurant resume examples

162. Helennut -- 2017-01-15 22:28

formal guidelines to writing a research paper essay writer co uk reviews

163. Helennut -- 2017-01-16 08:28

free youtube video downloader with resume free gcse french coursework

164. SusanArrix -- 2017-01-16 08:28

fallacy essay essay writing language techniques

167. Laurapails -- 2017-01-16 19:41

euthanasia essay assisted suicide should not be legal excent for university coursework http://win61.ru/go.php?go=http://shelfhelp.xyz

168. Juliedix -- 2017-01-17 04:58

food distributors business plan good ideas for english research papers http://autoadmit.com/go.php?url=http%3A%2F%2Fkovrick.us

170. Juliedix -- 2017-01-17 09:22

good and bad communication essay facebook popularity essay http://femdom.kinkest.com/cgi-bin/out.cgi?ses=xnhS7N6rbt&id=422&url=http://kaydoo.us

171. SarahOrent -- 2017-01-17 09:22

example of cover letter for government of canada free essay on stem cell research http://www.thassos-forum.com/go.php?to=http%3A//guliguli.us

176. ParisHiesy -- 2017-01-18 21:40

free resume manager free ap biology lab homework help exegetical essay essay writing made easy body paragraphs free recruiters resume search http://divavee.us

177. DonaldSem -- 2017-01-19 07:47

герпес на спине как избавиться http://ercancinar.xyz/index.php?viewurl=14135 воспаление простаты от камней в почках

178. DonaldSem -- 2017-01-19 07:47

чем можно вывести бородавку на руке в домашних условиях http://prettyfuckingawesome.xyz/index.php?link=1702 интернет аптека пиперазин цена

182. DonaldSem -- 2017-01-19 11:53

когда лучше удалять папилломы летом или зимой http://dubo188.xyz/index.php?viewurl=6111 увеит черные точки

183. DonaldSem -- 2017-01-19 11:53

эффективный заговор чтобы родственник бросил пить http://kartina-gobelen.ru/index.php?page-id=2191 единичное количество лейкоцитов в соке простаты

193. Clintonnib -- 2017-01-27 02:02

Сироп мангустина растопит до 10 кг жира за 2 недели! Спаситесь от ожирения и сократите риск инфаркта, диабета и гипертонии на 89%. Перейти на сайт: http://mangoo77.mangoosteen.com/

322. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

323. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

324. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

325. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

326. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

327. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

328. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

329. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

330. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

331. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

332. whvpywcq -- 2017-07-22 09:40

zq1hky05egraoxmoly <a href="https://bybklfn.info/">order baclofen</a> <a href=https://bybklfn.info/>buy generic baclofen</a> mdxv9kl7ds32bp2kpn

333. heaaymoc -- 2017-07-22 21:50

sr171v4bgb6jbjwj2p <a href="https://bybklfn.info/">buy generic baclofen</a> <a href=https://bybklfn.info/>baclofen online</a> 85vppssrksr25bimut

334. heaaymoc -- 2017-07-22 21:50

sr171v4bgb6jbjwj2p <a href="https://bybklfn.info/">buy generic baclofen</a> <a href=https://bybklfn.info/>baclofen online</a> 85vppssrksr25bimut

335. heaaymoc -- 2017-07-22 21:50

sr171v4bgb6jbjwj2p <a href="https://bybklfn.info/">buy generic baclofen</a> <a href=https://bybklfn.info/>baclofen online</a> 85vppssrksr25bimut

339. zd2yfr1n -- 2017-07-30 16:26

The serum concentration of Prednisone can be increased when it is combined with Sertraline. <a href=https://byprdnsn.info/>prednisone online</a>, steroid injection for urticaria - steroid injection for urticaria:

340. zd2yfr1n -- 2017-07-30 16:26

The serum concentration of Prednisone can be increased when it is combined with Sertraline. <a href=https://byprdnsn.info/>prednisone online</a>, steroid injection for urticaria - steroid injection for urticaria:

341. zd2yfr1n -- 2017-07-30 16:26

The serum concentration of Prednisone can be increased when it is combined with Sertraline. <a href=https://byprdnsn.info/>prednisone online</a>, steroid injection for urticaria - steroid injection for urticaria:

342. zd2yfr1n -- 2017-07-30 16:26

The serum concentration of Prednisone can be increased when it is combined with Sertraline. <a href=https://byprdnsn.info/>prednisone online</a>, steroid injection for urticaria - steroid injection for urticaria:

343. zd2yfr1n -- 2017-07-30 16:26

The serum concentration of Prednisone can be increased when it is combined with Sertraline. <a href=https://byprdnsn.info/>prednisone online</a>, steroid injection for urticaria - steroid injection for urticaria:

344. zd2yfr1n -- 2017-07-30 16:26

The serum concentration of Prednisone can be increased when it is combined with Sertraline. <a href=https://byprdnsn.info/>prednisone online</a>, steroid injection for urticaria - steroid injection for urticaria:

345. zd2yfr1n -- 2017-07-30 16:26

The serum concentration of Prednisone can be increased when it is combined with Sertraline. <a href=https://byprdnsn.info/>prednisone online</a>, steroid injection for urticaria - steroid injection for urticaria:

346. zd2yfr1n -- 2017-07-30 16:26

The serum concentration of Prednisone can be increased when it is combined with Sertraline. <a href=https://byprdnsn.info/>prednisone online</a>, steroid injection for urticaria - steroid injection for urticaria:

349. k05k5l9r -- 2017-07-31 08:11

Do not flush medications down the toilet or pour them into a drain unless instructed to do so. <a href=https://byprdnsn.info/>order prednisone</a>, prednisone dose for itchy dog

350. k05k5l9r -- 2017-07-31 08:11

Do not flush medications down the toilet or pour them into a drain unless instructed to do so. <a href=https://byprdnsn.info/>order prednisone</a>, prednisone dose for itchy dog

351. k05k5l9r -- 2017-07-31 08:11

Do not flush medications down the toilet or pour them into a drain unless instructed to do so. <a href=https://byprdnsn.info/>order prednisone</a>, prednisone dose for itchy dog

352. k05k5l9r -- 2017-07-31 08:11

Do not flush medications down the toilet or pour them into a drain unless instructed to do so. <a href=https://byprdnsn.info/>order prednisone</a>, prednisone dose for itchy dog

353. k05k5l9r -- 2017-07-31 08:11

Do not flush medications down the toilet or pour them into a drain unless instructed to do so. <a href=https://byprdnsn.info/>order prednisone</a>, prednisone dose for itchy dog

354. k05k5l9r -- 2017-07-31 08:12

Do not flush medications down the toilet or pour them into a drain unless instructed to do so. <a href=https://byprdnsn.info/>order prednisone</a>, prednisone dose for itchy dog

355. k05k5l9r -- 2017-07-31 08:12

Do not flush medications down the toilet or pour them into a drain unless instructed to do so. <a href=https://byprdnsn.info/>order prednisone</a>, prednisone dose for itchy dog

356. k05k5l9r -- 2017-07-31 08:12

Do not flush medications down the toilet or pour them into a drain unless instructed to do so. <a href=https://byprdnsn.info/>order prednisone</a>, prednisone dose for itchy dog

Add New Comment