0

Why my MSVS2008 compiler is not able to find implicit type conversion SrcT -> LPCSTR -> DstT when calling a function? This works fine in other cases. I do not like writing manual conversion all the time like following: MyFunc((LPCSTR)src). What I'm missing?

    MyFunc(src);

1>d:\test\test.cpp(39) : error C2664: 'MyFunc' : cannot convert parameter 1 from 'SrcT' to 'DstT'

#include <windows.h>
#include <tchar.h>

class SrcT
{
public:
    operator LPCSTR() const
    {
        return "dummy";
    }
};

class DstT
{
public:
    DstT() : m_value(NULL) {};
    DstT(LPCSTR value) {m_value = value; }
    DstT& operator=(LPCSTR value) { m_value = value; return *this; }

    LPCSTR m_value;
};

void MyFunc(DstT dst)
{
}

int _tmain(int argc, _TCHAR* argv[])
{
    SrcT src;
    DstT dst(src);
    DstT dst2;

    dst2 = src;
    MyFunc((LPCSTR)src);
    MyFunc(src);

    return 0;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Sergey
  • 1
  • I don't know the answer, but I can say that a similar program compiled with g++ errs: "x.cc:40: error: conversion from ‘SrcT’ to non-scalar type ‘DstT’ requested" – Robᵩ Sep 16 '11 at 22:28

1 Answers1

2

It's not just VS2008, all C++ compilers behave this way.

Two conversions are necessary to convert a SrcT to a DstT (SrcT->LPCSTR->DstT). However, the C++ standard states that only one user-defined conversion can be implicitly applied to a single value.

Section 12.3, Conversions

4 At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.

class X { // ...
    public:
        operator int();
};
class Y { // ...
    public:
        operator X();
};
Y a;
int b = a;    // error: a.operatorX().operator int() not tried
int c = X(a); // OK: a.operatorX().operator int()

See also this question.

Community
  • 1
  • 1
zpasternack
  • 17,838
  • 2
  • 63
  • 81
  • The strange thing is that in my understanding number of implicit conversions required for **dst2 = src;** and **MyFunc(src);** is the same. The second one has param as DstT, i.e. new instance of DstT has to be created inline from SrcT which is pretty much equivalent to invocation as following - MyFunc((dst2 = src)) - and which compiles fine. – Sergey Sep 17 '11 at 08:06