Consider following example.
The Idea is to exploit overloading operator= to automatically select one of multiple function calls from the required type (LinkKey or AttrKey). Currently, the programmer has to decide which one to call, which is prone to errors, and if it happens, very hard to debug.
Unfortunately it appears as if the compiler is unable to differentiate the calls, because the base type is always an int (the C2535 indicates this).
Is there any chance to make this work without doing anything to the LinkKey and AttrKey definitions, as that would be a major change?
The build environment is MSVC 2012.
** Update **
Changed to conversion operators. It was initially my assumption that an assignment happens, but know I know that the initialization is a special case.
The issue with both typedefs resolving to the same base type remains.
** Update 2**
I will scrap this as apparently it is not possible without modifiying the type definitions, and the inclusion of third party libraries.
#include <string>
#include <random>
// This is an example how the legacy interface works. It does not matter what it does internally. This is stuff that shall not be changed if possible.
typedef int LinkKey;
typedef int AttrKey;
class Store
{
public:
LinkKey LookupLinkKey( std::string key )
{
// random value is good enough for this example
return rand();
}
AttrKey LookupAttrKey( std::string key )
{
// random value is good enough for this example
return rand();
}
};
// This is my extension, that should protect vs. the failureTest shown below
class Key
{
public:
Key( std::string keystr )
: m_keystr( keystr )
{}
static void SetStore( Store* pStore )
{
s_pStore = pStore;
}
//LinkKey Key::operator= ( const Key& key )
//{
// LinkKey lk = s_pStore->LookupLinkKey( key.m_keystr );
// return lk;
//}
//AttrKey Key::operator= ( const Key& key ) // C2535: 'LinkKey Key::operator=(const Key&)' member function already defined or declared
//{
// AttrKey ak = s_pStore->LookupAttrKey( key.m_keystr );
// return ak;
//}
operator LinkKey() const
{
LinkKey lk = s_pStore->LookupLinkKey( m_keystr );
return lk;
}
operator AttrKey() const
{
AttrKey ak = s_pStore->LookupAttrKey( m_keystr );
return ak;
}
private:
std::string& m_keystr;
static Store* s_pStore;
};
Store* Key::s_pStore;
// Usage
void main( int argc, char* argv )
{
Store s;
Key::SetStore( &s );
LinkKey lk = Key("Link"); // C2440: cannot convert from 'Key' to 'LinkKey'
AttrKey ak = Key("Attribute"); // C2240: cannot convert from 'Key' to 'AttrKey'
LinkKey failureTest = s.LookupAttrKey("Foo"); // Ewwwwww...
}