The original problem was how to work with std::map<std::wstring, std::wstring> > in a secure way because equal types of the key and the value are extremely error-prone. So I decided to create a simple wrapper for the value:
struct ComponentName
{
std::wstring name;
// I want to prohibit any implicit string-ComponentName conversions!!!
explicit ComponentName(const std::wstring& _name) : name(_name)
{
}
bool operator<(const ComponentName& item_to_compare) const
{
return name < item_to_compare.name;
}
};
typedef std::map<std::wstring, ComponentName> component_names_map;
But the following code works well!
component_names_map component_names;
// Are you sure that ComponentName's constructor cannot be called implicitly? ;)
component_names_map::value_type a_pair = std::make_pair(L"Foo", L"Bar");
It works because the std::pair<std::wstring, ComponentName> copy constructor explicitly uses the string contructor of the ComponentName to assign the std::pair<std::wstring, std::wstring> instance. It's an absolutely legal operation. However it looks as an 'implicit' call of the ComponentName constructor.
So I know the reason of the problem, but how can I avoid this 'implicit' wstring-ComponentName conversion?
The simplest way is to not declare the string constructor, but it makes ComponentName initialization inconvenient.