2015-02-06 21 views
3

我知道这对C++ 11来说会更简单,但有没有办法使它在C++ 98中工作?我有以下示例代码:由某个数据成员对结构的STL容器进行排序

#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/bind.hpp> 
#include <vector> 
#include <algorithm> 
#include <iostream> 

struct foo { 
    foo(const int a_, const double b_): a(a_), b(b_) {} 
    int a; 
    double b; 
}; 

std::ostream &operator<<(std::ostream &out, const foo &f) 
{ 
    out << f.a << ',' << f.b; 
    return out; 
} 

#define DO_SORT(CONTAINER, TYPE, MEMBER) \ 
    std::sort(CONTAINER.begin(), CONTAINER.end(), boost::lambda::bind(&TYPE::MEMBER, boost::lambda::_1) > boost::lambda::bind(&TYPE::MEMBER, boost::lambda::_2)); 

int main() 
{ 
    std::vector<foo> v; 
    v.push_back(foo(1, -2.0)); 
    v.push_back(foo(3, -3.0)); 
    v.push_back(foo(2, -1.0)); 

    std::cout << "Original" << std::endl; 
    std::for_each(v.begin(), v.end(), std::cout << boost::lambda::_1 << "\n"); 
    std::cout << "Sort by a" << std::endl; 
    DO_SORT(v, foo, a); 
    std::for_each(v.begin(), v.end(), std::cout << boost::lambda::_1 << "\n"); 
    std::cout << "Sort by b" << std::endl; 
    DO_SORT(v, foo, b); 
    std::for_each(v.begin(), v.end(), std::cout << boost::lambda::_1 << "\n"); 
} 

这能够完成任务,但它要求容器内的类型来指定。我正在寻找一种能够写出DO_SORT(v, a)的方法。我尝试用BOOST_TYPEOF(CONTAINER)::value_type替换宏中的TYPE,但编译器不喜欢这样。

有没有办法在C++ 98中做到这一点,而不需要指定类型?另外,如果有一些方法可以减少甚至删除C++ 98中的宏,那么这也会很好。

+0

@JerryCoffin这不起作用,因为CONTAINER是容器的一个实例,而不是类型本身。 – 2015-02-06 18:24:07

+0

糟糕 - 我应该仔细阅读。抱歉。 – 2015-02-06 21:34:13

回答

2

可以消除宏观和使用模板参数推导的指针成员变量获取类型:

template <typename C, typename T, typename R> 
void do_sort(C& container, R T::*mem) { 
    std::sort(
     container.begin(), container.end(), 
     boost::lambda::bind(mem, boost::lambda::_1) > 
      boost::lambda::bind(mem, boost::lambda::_2)); 
} 

然后用语法调用

do_sort(v, &foo::a); 

这将由此实例:

void do_sort(std::vector<foo>& container, int foo::*mem); 

T将推断为fooR将推断为foo::a被声明为,以产生指向成员参数的正确类型。附注:我将这个功能命名为sort_by。一般的做法是使用<进行排序而不是>,但是如果你想要降序值,那么这就是要走的路。


为了完整起见,这里我将如何实现这在C++ 11

template <typename C, typename T, typename R> 
void sort_by(C& container, R T::*mem) { 
    std::sort(std::begin(container), std::end(container), 
      [mem](const T& lhs, const T& rhs) {return lhs.*mem > rhs.*mem;}); 
} 
+0

这样做。它仍然需要在容器中指定类型(即foo),但它没有宏而且我会接受它。另外,当我把这个例子放在一起时,调用sort_by这个名字和使用'>运算符'是一个复制和粘贴错误。 – 2015-02-06 18:33:05

0

你只是用这个作为一个例子,一般情况下,还是会像这样工作?

#include <iostream> 
#include <vector> 
#include <algorithm> 

struct foo { 
    foo(const int a, const double b) : a(a), b(b) {} 
    int a; 
    double b; 
}; 

bool compareA(const foo& foo1, const foo& foo2) 
{ 
    return foo1.a < foo2.a; 
} 

bool compareB(const foo& foo1, const foo& foo2) 
{ 
    return foo1.b < foo2.b; 
} 

int main() 
{ 
    std::vector<foo> v; 
    v.push_back(foo(1, -2.0)); 
    v.push_back(foo(3, -3.0)); 
    v.push_back(foo(2, -1.0)); 

    std::cout << "Original" << std::endl; 
    for (int i = 0; i < v.size(); i++) std:: cout << v[i].a << '\n'; 
    std::cout << "Sort by a" << std::endl; 
    std::sort(v.begin(), v.end(), compareA); 
    for (int i = 0; i < v.size(); i++) std:: cout << v[i].a << '\n'; 
    std::cout << "Sort by b" << std::endl; 
    std::sort(v.begin(), v.end(), compareB); 
    for (int i = 0; i < v.size(); i++) std:: cout << v[i].b << '\n'; 
} 
+0

我同意作品,但它需要大量的“锅炉板”(定义比较函数和使用.begin()/。end())。我希望在C++ 98/03代码中没有必要的函数定义和尽可能简单的接口。 – 2015-02-06 18:26:03

相关问题