【发布时间】:2011-11-15 11:20:03
【问题描述】:
最初的问题是如何以安全的方式使用std::map<std::wstring, std::wstring> >,因为相同类型的键和值非常容易出错。所以我决定为这个值创建一个简单的包装器:
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;
但是下面的代码运行良好!
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");
之所以有效,是因为 std::pair<std::wstring, ComponentName> 复制构造函数显式使用 ComponentName 的字符串构造函数来分配 std::pair<std::wstring, std::wstring> 实例。这是绝对合法的操作。但是,它看起来是对 ComponentName 构造函数的“隐式”调用。
所以我知道问题的原因,但是如何避免这种“隐式”wstring-ComponentName 转换?
最简单的方法是不声明字符串构造函数,但是这样会使得 ComponentName 初始化不方便。
【问题讨论】:
-
+1 提出了一个很好的问题。
-
我不认为您可以阻止某人为您的显式构造函数编写隐式转换包装器...
-
也许你可以为你的类型写一个工厂函数。
-
请注意,用户应该编写的代码,即
value_type a_pair(L"Foo", L"Bar");,确实是正确禁止的。 C++ 不是要强制执行绝对值,而是要让编写错误代码变得困难,并让编写正确代码变得容易。我认为你的设计在这方面是足够的。 -
你真正想要的是
friend的反面——也许是一种enemy关键字?