std :: map中Key类型的赋值运算符要求

时间:2014-12-01 03:21:00

标签: c++ c++11 clang++

似乎在这里建议What requirements must std::map key classes meet to be valid keys?,在其他一些帖子中,srd :: map的Key类型必须有赋值运算符。但是我无法在标准中找到该要求。

#include <map>

struct Foo
{
    Foo& operator=( const Foo& ) = delete;

    int id;
};

bool operator<( const Foo&, const Foo& ) { return( false ); }

int main( int, char** )
{
    std::map<Foo,int> a;
    std::map<Foo,int> b;

    a = b;   // Should this work if Foo does not have an assignment operator?

    return( false );
}

上面用GCC 4.9和Visual Studio 2013进行编译但失败了,抱怨缺少赋值运算符,在Ubuntu 14.10框上使用clang 3.5运行以下命令“clang ++ -std = c ++ 11 -stdlib = libc ++ code.cpp”。使用GCC标准库时,Clang确实成功了。我怀疑clang标准库在这里被打破了。

1 个答案:

答案 0 :(得分:4)

§23.1[container.requirements.general] / p15&amp;表99:

  

在表99中,X表示具有分配器的容器类   使用value_type类型的分配器T A ua表示   变量bX表示tX类型的非常量左值   表示rv类型的左值或常量值,X表示a   类型为m的非const rvalue,A+-----------+-------------+--------------------------------+------------+ |Expression | Return type | Assertion/note | Complexity | | | | pre-/post-condition | | |-----------+-------------+--------------------------------+------------+ | a = t | X& | Requires: T is CopyInsertable | linear | | | | into X and CopyAssignable. | | | | | post: a == t | | +-----------+-------------+--------------------------------+------------+ 类型的值。

表99的相关部分(可识别分配器的容器要求)是:

map

然后§23.2.4[associative.reqmts] / p7说

  

关联容器满足所有要求   分配器感知容器(23.2.1),但multimapvalue_type除外   key_type,表96中mapped_type的要求适用   而是key_typemapped_type。 [注意:例如,在某些情况下   案例CopyAssignablevalue_type必须为pair<const key_type, mapped_type>   即使关联的CopyAssignableCopyAssignable不是value_type。 - 结束记录]

请注意,这引用了表96,但是给出了注释,意图显然也包括表99,因为表96中的任何内容实际上都不需要pair<const key_type, mapped_type>。由于CopyAssignable,{{1}}永远不会{{1}},因此阅读表99要求来引用它将是相当荒谬的。