相关疑难解决方法(0)

除了允许变量被const函数修改之外,'mutable'关键字是否有任何其他用途?

前段时间我遇到了一些用mutable关键字标记类的成员变量的代码.据我所知,它只是允许您修改const方法中的变量:

class Foo  
{  
private:  
    mutable bool done_;  
public:  
    void doSomething() const { ...; done_ = true; }  
};
Run Code Online (Sandbox Code Playgroud)

这是这个关键字的唯一用途,还是有更多的东西比它的眼睛?我已经在一个类中使用了这个技术,标记为一个boost::mutex可变的允许const函数为了线程安全的原因锁定它,但是,说实话,这感觉有点像黑客.

c++ mutable keyword

511
推荐指数
12
解决办法
21万
查看次数

什么是透明比较器?

在C++ 14中,关联容器似乎已从C++ 11改变 - [associative.reqmts]/13说:

成员函数模板find,count,lower_bound,upper_bound,并且equal_range不得,除非类型参与重载决议Compare::is_transparent存在.

使比较器"透明"的目的是什么?

C++ 14还提供了这样的库模板:

template <class T = void> struct less {
    constexpr bool operator()(const T& x, const T& y) const;
    typedef T first_argument_type;
    typedef T second_argument_type;
    typedef bool result_type;
};

template <> struct less<void> {
    template <class T, class U> auto operator()(T&& t, U&& u) const
    -> decltype(std::forward<T>(t) < std::forward<U>(u));
    typedef *unspecified* is_transparent;
};
Run Code Online (Sandbox Code Playgroud)

因此,例如,std::set<T, std::less<T>>将不会有一个透明的比较,而是std::set<T, std::less<>> …

c++ c++-faq c++14

101
推荐指数
4
解决办法
2万
查看次数

是否有更高效的双向映射实现?

我创建了一个简单的双向映射类,它通过内部存储两个std::map具有相反键/值类型的实例,并提供用户友好的界面:

template<class T1, class T2> class Bimap
{
    std::map<T1, T2> map1;
    std::map<T2, T1> map2;
    // ...
};
Run Code Online (Sandbox Code Playgroud)
  • 是否有更有效的方法来实现不需要两倍内存的双向映射?

  • 通常如何实施bimap?


编辑:

  • bimap元素应该是可变的还是不可变的?(更改一个元素map1应该更改键map2,但键是常量,这是不可能的 - 解决方案是什么?)

  • 元素的所有权也是另一个问题:当用户在bimap中插入键值对时,bimap应该复制该键值对并存储它,然后内部第二个映射(具有反转的键/值)应该不复制,但指向原始对.怎么能实现这一目标?


编辑2:

我发布了一个关于Code Review的可能实现.

c++ map bimap data-structures c++11

53
推荐指数
5
解决办法
2万
查看次数

对unique_ptrs集的原始指针查找

我经常发现自己想写这样的代码:

class MyClass
{
public:
  void addObject(std::unique_ptr<Object>&& newObject);

  void removeObject(const Object* target);

private:
  std::set<std::unique_ptr<Object>> objects;
};
Run Code Online (Sandbox Code Playgroud)

但是,很多std :: set接口对std :: unique_ptrs都没用,因为查找函数需要std :: unique_ptr参数(我显然没有这些参数,因为它们由集合本身拥有).

我可以想到两个主要的解决方案.

  1. 创建临时unique_ptr以进行查找.例如,上面的removeObject()可以实现如下:

    void MyClass::removeObject(const Object* target)
    {
      std::unique_ptr<Object> targetSmartPtr(target);
      objects.erase(targetSmartPtr);
      targetSmartPtr.release();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将原始指针映射替换为unique_ptrs.

      // ...
      std::map<const Object*, std::unique_ptr<Object>> objects;
    };
    
    Run Code Online (Sandbox Code Playgroud)

然而,对我来说,两者似乎都有点愚蠢.在解决方案1中,erase()不是noexcept,因此临时unique_ptr可能会删除它实际上不拥有的对象,而2需要不必要地为容器存储两倍.

我知道Boost的指针容器,但与现代C++ 11标准库容器相比,它们目前的功能有限.

我最近在阅读有关C++ 14的内容,并且遇到了"将异构比较查找添加到关联容器".但是形成我对它的理解,查找类型必须与键类型相当,但原始指针不能与unique_ptrs相比.

任何人都知道更优雅的解决方案或即将添加的C++解决了这个问题?

c++ unique-ptr c++11 c++14

40
推荐指数
1
解决办法
3996
查看次数

如何通过多个键索引和查询STL映射容器?

我遇到了一个记录存储为的要求

Name :  Employee_Id  :  Address
Run Code Online (Sandbox Code Playgroud)

其中Name和Employee_Id应该是键,在Name和Employee Id上都提供搜索功能.

我可以考虑使用地图来存储这个结构

std::map< std:pair<std::string,std::string> , std::string >  
//      <         < Name   ,   Employee-Id> , Address     > 
Run Code Online (Sandbox Code Playgroud)

但我不确定搜索功能的样子.

c++ containers stl

15
推荐指数
1
解决办法
2万
查看次数

使用STL的红黑树的内部实现

据我所知,我的STL(g ++ 4.xx附带)使用红黑树来实现地图等容器.是否可以直接使用STL的内部红黑树.如果是这样,怎么样?如果没有,为什么不 - 为什么STL不暴露红黑树?

令人惊讶的是,我无法使用谷歌找到答案.

编辑:我正在调查使用红黑树作为插入时额外的allocator构造函数调用的解决方案.看到这个问题.我的STL使用红黑树来实现地图.

c++ tree stl red-black-tree

11
推荐指数
1
解决办法
1万
查看次数

是否可以使用与std :: set中包含的不同类型的元素来执行搜索和删除?

假设我有以下内容:

struct MetadataThingy {

    void *actual_thingy;
    int some_metadata;
    int more_metadata;

    bool operator<(MetadataThingy const& other) const {
        return actual_thingy < other.actual_thingy;
    }

};
Run Code Online (Sandbox Code Playgroud)

其中actual_thingy指向一些重要数据,我希望容器按值actual_thingy而不是指向的元素的值排序,但是我需要存储一些关于它的其他数据,所以我MetadataThingy用一个只考虑的比较器创建了包装类actual_thingy指针的值(而不是使用容器void *)

现在,给出以下代码:

std::set<MetadataThingy> thingy_set;

void test() {

    MetadataThingy m1 { nullptr, 5, 20 };
    MetadataThingy m2 { &m1, 1, 2 };
    MetadataThingy m3 { &m2, 6, 0 };

    thingy_set.insert(m1);
    thingy_set.insert(m2);
    thingy_set.insert(m3);

    MetadataThingy m;
    m = *thingy_set.find(m2); // OK.
    m = *thingy_set.find(static_cast<void *>(&m2)); // Nope. Can't use a …
Run Code Online (Sandbox Code Playgroud)

c++ set stdset

5
推荐指数
1
解决办法
757
查看次数