C ++ - 隐式删除了复制赋值运算符

时间:2016-02-09 18:54:53

标签: c++ templates

我尝试在以下情况下使用复制分配。

有两个模板类list mapxpair

template <typename Key, typename Value, class Less=xless<Key>>
class listmap {
public:
   using key_type = Key;
   using mapped_type = Value;
   using value_type = xpair<const key_type, mapped_type>;     //value_type
...
}

template <typename First, typename Second>
struct xpair {
   First first{};
   Second second{};
   xpair(){}
   xpair (const First& first, const Second& second):
           first(first), second(second) {}
};

在main.cpp中,我试着写,

using commend = string;
using str_str_map = listmap<string,string>;
using str_str_pair = str_str_map::value_type;    //value_type, to be replaced
using commend_pair = xpair<commend, str_str_pair>;

int main(...) {
   commend_pair cmd_pair;
   str_str_pair newPair ("Key", "value");
   cmd_pair.second = newPair;

   ...
}

它给我一个错误说

  object of type 'xpair<const std::__1::basic_string<char>,
  std::__1::basic_string<char> >' cannot be assigned because its copy
  assignment operator is implicitly deleted

如果我更换

using str_str_pair = str_str_map::value_type;

using str_str_pair = xpair<string, string>;

一切正常。这是为什么?不应该value_type = xpair<string, string>吗?

2 个答案:

答案 0 :(得分:7)

我没有看到声明newPair的位置,但错误信息似乎已经足够了。

为什么会失败:如果pair中的任何一个元素都是const,那么该元素的赋值运算符本身就会被删除。您无法分配到const string,但这正是您在分配给pair<const string, T>时要求它执行的操作。简化示例

std::pair<const int, int> p(0, 0);
p.first = 1; // no, can't assign to p.first
p = std::pair<const int, int>(1, 2); // no, requires assigning to p.first

为什么地图有const个键类型map容器根据键组织元素。如果您更改了密钥,则地图将无法再找到它。考虑:

std::map<string, int> m = { ... };
auto it = m.find(k);
it->first = "a different value";

由于例如std::map在内部被组织为红黑树,因此安全地更改密钥将需要重新组织节点。但是,在此示例中,您可以直接在节点中的pair上操作。更改key需要从m中删除该对,然后将其重新置于更改后的key

答案 1 :(得分:5)

你有

const key_type

由于您使用的是key_type,因此constusing str_str_pair = xpair<string, string>; ,您无法再分配给它。

string

不适用于const @Bean(name = "freemarkerConfig") public FreeMarkerConfigurer freemarkerConfig() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("/WEB-INF/views/"); Map<String, Object> map = new HashMap<>(); map.put("xml_escape", new XmlEscape()); configurer.setFreemarkerVariables(map) def settings = new Properties() settings['auto_import'] = 'spring.ftl as spring, layout/application.ftl as l' configurer.setFreemarkerSettings(settings) println "returning freemarker config" return configurer; }