【问题标题】:c++ overwrite [] operator with std::string [closed]c ++用std :: string覆盖[]运算符[关闭]
【发布时间】:2018-12-30 05:47:27
【问题描述】:

我基本上是在尝试为std::map 创建一个线程安全的包装类。 由于我来自 C,我很难弄清楚 C++ 的所有细微差别。 我正在尝试覆盖[] operator 以获取std::string 参数,以便将其传递给我的std::map 成员。 通过std::map::operator[] 的引用,这应该可以正常工作:

T& operator[]( const Key& key );

这是我的课:

thread_map.hpp

#ifndef THREAD_MAP_H
#define THREAD_MAP_H

#include <map>
#include <functional>
#include <mutex>

template <class T>class Thread_map
{
private:
    std::map<std::string, T> map;
    std::mutex map_mutex;

public:

    ~Thread_map();

    T& at(size_t pos);
    T& operator[](std::string &key);

    size_t size() const;
    bool empty() const;

    void clear();
    void insert(std::pair<std::string, T> pair);
    T& erase(const std::string &key);

    bool for_each(std::function<bool (Thread_map, std::string&, T&)> fun);
};

template<class T> Thread_map<T>::~Thread_map()
{
    this->map.clear();
}

template<class T> T& Thread_map<T>::at(size_t pos)
{
    T *value;
    this->map_mutex.lock();
    value = this->map.at(pos);
    this->map_mutex.unlock();
    return value;
}

template<class T> T& Thread_map<T>::operator[](std::string &key)
{
    this->map_mutex.lock();
    T &value = this->map[key];
    this->map_mutex.unlock();
    return value;
}

template<class T> size_t Thread_map<T>::size() const
{
    size_t size;
    this->map_mutex.lock();
    size = this->map.size();
    this->map_mutex.unlock();
    return size;
}

template<class T> bool Thread_map<T>::empty() const
{
    bool empty; 
    this->map_mutex.lock();
    empty = this->map.empty();
    this->map_mutex.unlock();
    return empty;
}

template<class T> void Thread_map<T>::clear()
{
    this->map_mutex.lock();
    this->map.clear();
    this->map_mutex.unlock();
}

template<class T> void Thread_map<T>::insert(std::pair<std::string, T> pair)
{
    this->map_mutex.lock();
    this->map.insert(pair);
    this->map_mutex.unlock();
}

template<class T> T& Thread_map<T>::erase(const std::string &key)
{
    T *value;
    this->map_mutex.lock();
    value = this->map.erase(key);
    this->map_mutex.unlock();
    return value;
}

template<class T> bool Thread_map<T>::for_each(std::function<bool 
(Thread_map, std::string&, T&)> fun)
{

}


#endif

我把实现放到了头文件中,因为我听说你是用模板类来做的。我是对的吗? 我的问题是,当我尝试打电话给运营商时

Thread_map<std::string> map;
map["mkey"] = "value";

g++ 在 map["mkey"] 上抛出一个无效的初始化错误。 据我了解,问题在于mkey 被编译为std::string("mkey"),这只是值,而不是参考。 但是为什么或如何以下工作呢?

std::map<std::string, std::string> map;
map["mkey"] = "value";

我的意思是我可以按值传递字符串,但这似乎效率低下。

【问题讨论】:

  • 比较T&amp; operator[]( const Key&amp; key )T&amp; Thread_map&lt;T&gt;::operator[](std::string &amp;key)。前者中存在一个关键字,而后者中缺少一个关键字。提示:以c 开头,以t 结尾。
  • 谢谢忽略了:D
  • 您的代码似乎充满了错误。
  • 你能告诉我错误是什么或不是Kkid。我对 C++ 有点陌生?好吧,请您参考飞翔的那个链接:*.com/questions/8752837/…
  • @pear 尝试erase 字典中的一个键,使用empty 函数,使用size 函数(提示-emptysize 问题是同一种),并使用at 函数。

标签: c++ templates stdmap


【解决方案1】:

引用需要一个可以修改的变量地址。对于左值字符串(“某些字符串”),没有可以修改值的地址。 我知道有一些方法可以解决这个问题:

删除参考(不推荐)

一种方法是从参数中删除“&”。像这样:

T& operator[](std::string key);

通过这种方式,您不需要请求左值,而是请求右值。问题是,当你发送一个值时,你不会发送 4 个字节的内存地址,而是 sizeof("Your string") 个字节。重法..

制作一个 const 左值(推荐方式)

解决这个问题最好的方法,就是让参数为 const lvalue(即rvalue reference),向编译器承诺你不会尝试在这个函数中改变给定地址的值.它看起来像这样:

T& operator[](const std::string &key);

现在您可以发送左值字符串和右值字符串。

放弃

这种方式不如第一种,但绝对不如第二种。您可以轻松地使用您的声明:

T& operator[](std::string &key);

并且当你传递一个值时,使用另一个字符串变量来存储该值,并在调用时使用这个变量:

Thread_map<std::string> map;
string key = "mkey";
map[key] = "value";

(不要那样做。只是作为知识的扩展)。

【讨论】:

  • 一个小问题的尝试不错,但整个代码似乎是 FUBAR ))
  • @KillzoneKid 谢谢!顺便说一句,为他解决这些问题没有问题,但我不想打扰他的乐趣:)
  • 非常感谢您的回答:)
  • “使参数为 const rvalue”,然而,你有一个左值引用。