【问题标题】:Why does this std::sort predicate fail when the class is inside main()?当类在 main() 中时,为什么这个 std::sort 谓词会失败?
【发布时间】:2011-10-16 08:13:21
【问题描述】:

这是一个非常简化的重现,它说明了 class Predicatemain() 之外如何工作,但是当确切的代码内联显示为 class InlinePredicate 时,编译器无法匹配 std::sort。奇怪的是,你可以将 anything 作为第三个参数传递给std::sort(比如整数7),当它不支持operator () 时,你只会得到一个编译错误。 987654327@ 预计。但是当我通过下面的pred2 时,它根本不匹配:

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Predicate {
public:
    bool operator () (const pair<string,int>& a, const pair<string,int>& b)
    {
        return a.second < b.second;
    }
};

int
main()
{
    vector<pair<string, int> > a;

    Predicate pred;
    sort(a.begin(), a.end(), pred);

    class InlinePredicate {
    public:
        bool operator () (const pair<string,int>& a, const pair<string,int>& b)
        {
            return a.second < b.second;
        }
    } pred2;
    sort(a.begin(), a.end(), pred2);

    return 0;
}

repro.cc:在函数“int main()”中:

repro.cc:30: 错误: 没有匹配函数调用 'sort(__gnu_cxx::__normal_iterator, std::allocator >, int>*, std::vector, std::allocator >, int>, std ::allocator, std::allocator >, int> > > >, __gnu_cxx::__normal_iterator, std::allocator >, int>*, std::vector, std::allocator >, int>, std::allocator, std::allocator >, int> > > >, main()::InlinePredicate&)'

【问题讨论】:

  • 附带说明:您的运营商可能应该是 const bool operator()(const pair&lt;string,int&gt;&amp; a, const pair&lt;string,int&gt;&amp; b) **const**

标签: c++ templates stl


【解决方案1】:

在 C++03 中,本地类没有链接,因此不能用作模板参数(第 14.3.1/2 节)。

在 C++0x 中,此限制已被删除,您的代码将按原样编译。

【讨论】:

  • 您可能仍然应该将谓词的运算符设为const,因为sort 可能需要这样做。
  • 它使用g++ -std=c++0x 编译 GCC 4.5(不是 4.3,我手边没有 4.4)
【解决方案2】:

在 C++0x 之前的 C++ 版本中,在函数内部声明的类不能出现在模板参数中。您对sort 的调用隐式地使用设置为InlinePredicate 的模板参数实例化它,这是非法的。

您可能要考虑使用 C++0x(使用 GCC,传递 --std=c++0x;在 C++0x 中,此代码将按原样工作,或者您可以使用匿名函数)或 boost::lambda。使用boost::lambda,它看起来像这样:

using namespace boost::lambda;

sort(a.begin(), a.end(), _1 < _2);

【讨论】:

  • 请注意,从 Boost 1.47 开始,Boost.Lambda 已正式弃用,取而代之的是 Boost.Phoenix v3。因此,使用 Phoenix 而不是 Lambda 的新代码会更好(并且您为 sort 调用显示的语法将保持不变)。
  • @ildjarn,哦,太好了,又一个 C++03 匿名函数 hack 来学习... :)
  • 但功能更强大,绝对值得。 :-] 即使在 C++0x 中,我也倾向于在 C++0x lambda 上使用 Phoenix 仿函数,因为它们是多态的。
猜你喜欢
  • 2019-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多