最初的问题是如何与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>
复制构造函数显式使用组件名称的字符串构造函数来分配std::pair<std::wstring, std::wstring>
实例。这是绝对合法的操作。然而,它看起来像是 ComponentName 构造函数的“隐式”调用。
所以我知道问题的原因,但如何避免这种“隐式”wstring-ComponentName
转换?
最简单的方法是不声明字符串构造函数,但这使得 ComponentName 初始化不方便。
我认为你可以通过添加部分专业化来合法地做到这一点std::pair
适合您的类型:
namespace std {
template <typename T>
struct pair<T,ComponentName> {
typedef T first_type;
typedef ComponentName second_type;
T first;
ComponentName second;
// The rest of the pair members:
// ....
// Any trick you like to make it fail with assignment/construction from
// pair<std::wstring, std::wstring>
};
}
理由:
§ 17.6.4.2.1 规定了专业化的基本规则std
命名空间:
“程序可以为任何标准库添加模板专门化
仅当声明依赖于 a 时,模板才到命名空间 std
用户定义类型且专业化符合标准库
原始模板的要求并没有明确
禁止”
如果您在 § 20.3 的范围内填写了课程的其余部分,我看不到任何明确的禁止可以排除这种特殊情况。
替代的、可能合法的方法:
专精std::is_constructible<ComponentName, std::wstring>
这样value
是假的。这被列为赋值运算符和复制构造函数的要求std::pair
不同类型的。快速扫描我也看不到任何禁止,但我找不到任何说明实现是required检查要求。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)