如何在std :: map中停止从int到float的自动转换,反之亦然

时间:2014-09-12 13:28:40

标签: c++ dictionary std stdmap c++-standard-library

我在这里写了一个使用std::map的小程序,如下所示。

int main()
{
  map<int,float>m1;
  m1.insert(pair<int,float>(10,15.0));   //step-1
  m1.insert(pair<float,int>(12.0,13));   //step-2
  cout<<"map size="<<m1.size()<<endl;    //step -3

我创建了一个地图,其中int类型为键,浮点类型为地图m1的值(键值)对

  1. 创建一个普通的int-float对并插入映射。

  2. 创建一个cross float-int对并插入到map中。现在我知道隐式转换正在使这对插入映射。

  3. 这里我只是不希望发生隐式转换,应该给出编译器错误。

    在我们尝试执行step-2类型操作时,我必须在此程序/映射中进行哪些更改才能使comipiler标记出错?

3 个答案:

答案 0 :(得分:6)

这是一个建议:

template <typename K, typename V, typename W>
void map_insert(map<K,V>& m, K k, W w) {
  V v = w;
  m.insert(pair<K,V>(k,v));
}

int main() {
  map<int,float>m1;
  map_insert(m1, 10, 15.0);
  map_insert(m1, 12.0, 13);  // compiler complains here
  cout<<"map size="<<m1.size()<<endl;

第三个模板参数有点尴尬但是必须允许从double转换为float

答案 1 :(得分:3)

这是不可能的(即使有可能,那么你也不应该主要黑客)。

insertvalue_type为参数,为pair<int const,float>。 因此,当您尝试插入pair<float, int>时,编译器会查找转换,即:pair<int const, float>的构造函数,它将pair<float, int>作为参数,它只是存在。事实上,我试图为该模板成员(允许转换)提供部分特化,然后您可能在剩余的模板参数上失败,但我没有这样做;似乎不可能。无论如何,这将是一个非常肮脏的黑客,你不应该只是为了避免打字错误。在其他地方,您可能需要进行此转换,并且无论如何都无法在命名空间std中定义任何内容。

那么&#34的解决方案是什么?我怎样才能避免这种拼写错误?&#34; ?

这是我通常做的事情:

1)我的所有地图都有类型的typedef 2)然后我专门对该类型使用::value_type(和::iterator等)。

这不仅更强大,而且更灵活:您可以稍后更改容器类型,代码可能仍然有效。

所以,你的代码将成为:

int main()
{
  typedef std::map<int,float> m_type;
  m_type m1;

  m1.insert(m_type::value_type(10,15.0));   // allowed
  m1.insert(m_type::value_type(12.0,13));   // no risk for a typo.

另一种解决方案是将float包装在自定义类中。对于(再次)灵活性的原因而言,这不是一件坏事。使用std::map<int, builtin-type>编写代码然后意识到您需要存储更多数据并且相信我发生了很多事情,这很难。你可以从一开始就开始上课。

答案 2 :(得分:2)

可能有一种更简单的方法,但这就是我发生的事情:

#include <iostream>
#include <map>

template<typename Key, typename Value>
struct typesafe_pair
{
    const Key& key;
    const Value& value;
    explicit typesafe_pair(const Key& key, const Value& value): key(key), value(value) {}

    operator typename std::map<Key, Value>::value_type() { return typename std::map<Key, Value>::value_type(key, value); }
};

int main()
{
  std::map<int,float>m1;

  m1.insert(std::pair<int,float>(10,15.0));   // allowed
  m1.insert(std::pair<float,int>(12.0,13));   // allowed!!

  m1.insert(typesafe_pair<int,float>(10, 15.0)); // allowed
  m1.insert(typesafe_pair<float, int>(12.0, 13)); // compiler error

  std::cout << "map size=" << m1.size() << std::endl;    //step -3
}

编辑:1 有人可能能够提供更好(更有效)的解决方案,包括右值参考和完美的转发魔法,我还没有完全掌握。

编辑2:我认为 Carlo Wood 拥有最佳解决方案恕我直言。