Visual C++关系运算符重载const修饰(使用std::sort)

3
在下面的示例代码中,重载运算符<没有被const限定,它可以在Visual C++(所有版本都适用到2013 Preview)下编译通过,但是在Clang下,它会抛出一个错误-注意:候选函数不可行:'this'参数具有类型'const Entry',但方法未标记为const bool operator<( const Entry& other )。
#include "stdafx.h"
#include <vector>
#include <algorithm>

struct Entry
{
    unsigned int age;
    bool operator<( const Entry& other ) // !!! no const qualification here !!!
    {
        return age < other.age;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<Entry> entries;
    for( unsigned int i = 0; i < 100; ++i )
    {
        Entry entry;
        entry.age = i;
        entries.push_back( entry );
    }
    // Sort by age
    std::sort( entries.begin(), entries.end() );
    return 0;
}

Visual C++在强制执行比较/关系运算符的const正确性方面是否不符合标准?或者这与std::sort有关?

3
可能是std::sort实现的问题:clang在const上下文中比较对象,而VC++则没有。 一般情况下,当clang和VC++意见不一致时,通常是因为VC++的实现存在错误。 :) - Yakk - Adam Nevraumont
1个回答

3
C++标准规定,假定通过解引用的迭代器不会应用非常量函数,首先是通过将其表述为可传递给sort的Compare函数对象来说明:

“Compare是一个函数对象类型(20.8)。当将上下文转换为bool(4)时,应用于类型为Compare的对象的函数调用操作的返回值,如果调用的第一个参数小于第二个参数,则产生true,否则产生false。 Compare comp在假定存在排序关系的算法中使用。假定comp不会通过解引用的迭代器应用任何非常量函数。”

(强调是我的)

然后,通过说明Compare和operator <之间的关系来阐述:

“对于所有采用Compare的算法,都有一个使用operator <的版本。也就是说,comp(*i,*j)!= false默认为*i < *j!= false。为了使除25.4.3中描述的算法之外的其他算法正常工作,comp必须对值引入严格的弱序关系。”

以上两个引用来自C++标准库。从25.4“排序及相关操作”中得出。

因此,虽然没有明确说明成员operator <必须是const,但假设它是const意味着它必须是const。限制comp而不限制operator <是没有意义的。

我认为Visual C++在这里有问题,因为它允许在解引用的迭代器上调用非const函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接