I'm converting a project from VS 6.0 SP5 to VS 2005 rc. I'm getting this really odd C2664 error. Unfortunately, the project is very complex and I have not yet been able to reproduce this behavior with a simple example. I can, however, offer proof of its strangeness:
DBString dbx = m_scCal.operator const DBString();
DBString dby = m_scCal;
DBString dbz = ( const DBString )m_scCal;
Of the three example statements above, only the first one compiles. I have no idea how it is that an explicit invocation of a converstion operator via the "." syntax can work, but explicit conversion through the type-cast syntax does not.
The error I get depends on whether or not I attempt an explicit or implicit conversion of the original type.
Note: the typedef "typedef CPVString DBString" exists in the preprocessor input stream for these source files.
An explicit conversion attempt yields:
c:\development\turboese_64\database\schema\objects.cpp(39) : error C2440: 'initializing' : cannot convert from 'const ft_structure_code' to 'CPVString'
No constructor could take the source type, or constructor overload resolution was ambiguous
An implicit conversion attempt yields the more informative:
c:\development\turboese_64\database\schema\objects.cpp(1606) : error C2664: 'CConstraintBase::ConstraintTypeToEnum' : cannot convert parameter 1 from 'ft_text' to 'const CPVString &'
Qualification conversion
followed by
Call to user-defined-conversion 'TDBField<managed_type>::operator const DBString(void) const'
with
[
managed_type=DBFieldString
]
c:\development\turboese_64\database\dbenviron.h(906) : see declaration of 'TDBField<managed_type>::operator const DBString'
with
[
managed_type=DBFieldString
]
followed by
Exactly the same type
followed by
Call to user-defined-conversion 'TDBField<managed_type>::operator const DBFieldString &(void) const'
with
[
managed_type=DBFieldString
]
c:\development\turboese_64\database\dbenviron.h(912) : see declaration of 'TDBField<managed_type>::operator const DBFieldString &'
with
[
managed_type=DBFieldString
]
followed by
Binding to reference
The above error seems particularly strange, given that the diagnostic information it provides seems to show a perfectly acceptable conversion path. Why didn't it use it
I set up the following code fragment in an attempt to reproduce this behavior, but it works perfectly:
typedef char _TCHAR;
typedef const char *LPCTSTR;
class
CPVString{
public : CPVString ();
CPVString ( _TCHAR, int );
CPVString ( LPCTSTR lpch, int nLength );
public : virtual ~CPVString ();
public : CPVString ( const CPVString & );
CPVString ( LPCTSTR );
};
typedef
CPVString DBString;DBString ConvertToDBString()
{
return ( DBString() );
}
template
< class managed_type, int nBindingCount = 4 > class TDBField{
public : operator const DBString () const { return ( ConvertToDBString() ); }
};
typedef
TDBField< bool > ft_Foo;class
CBar{
public : void SomeFunc() const
{
DBString dby = ( const DBString )m_fooData;
}
private : ft_Foo m_fooData;
};
The above is extracted directly from my code, although the various class definitions did not originally reside in the same include file and have also been truncated for brevity.

Strange C2664 in Visual Studio 2005 C++ release candidate (v8.0.50727.26)
Andr&#233; Brisebois
If, by coincidence T1 was a C1 (or was derived from C1) then the compiler would determine that the conversion operator choice was ambiguous. In VC 6.0, you could get away with this if you invoked the conversion operator through a static type cast. In VC 2005 RC, this isn't good enough and the selection is still considered ambiguous.
This is a real pain for me, but I can't find any language rule that says this behavior is wrong.
C'est la vie.