如何有效地使用包含来自其他源文件的运算符的结构定义?

时间:2013-10-03 17:55:58

标签: c++ struct namespaces operators

我有一个由几个子模块组成的项目。因为我有一些结构,例如Point或Rectangle,我想要一个单独的头文件,其中定义了这些数据结构及其运算符。然后,其他源文件包含此内容。我有

structures.hpp

namespace datastructures {
    struct Rectangle {
         int width;
         int height;
    };


bool operator<=(const Rectangle& lhs, const Rectangle& rhs){
    return lhs.width <= rhs.width;
} 
}// end namespace

Algorithm.hpp

我有另一个文件Algorithm.hpp,看起来类似于:

#include "structures.hpp"
class Algorithm {
public:
     typedef datastructures::Rectangle Rectangle;
     void func1(int median);
private:
     std::vector<Rectangle> rectangles_;
}

这编译一切都很好。但是使用运算符似乎根本不起作用。

Algorithm.cpp

void Algorithm::func1(int median){
     std::nth_element(rectangles_.begin(), 
     rectangles_.begin() + median, rectangles_.end(), datastructures::operator<=);
}

这会给模板带来编译错误,最有意义的是

no matching function for call to 
‘nth_element(std::vector<datastructures::Rectangle>::iterator&, 
std::vector<datastructures::Rectangle>::iterator&, 
std::vector<datastructures::Rectangle>::iterator&, 
<unresolved overloaded function type>)’ 

为什么它不知道我的datastructures头文件中的operator<=

2 个答案:

答案 0 :(得分:2)

错误是由于:

unresolved overloaded function type

必须有多个匹配签名的运算符。 您可以使用类似boost::function或函数指针的选项来选择特定的重载或使用比较器仿函数http://en.cppreference.com/w/cpp/utility/functional/less_equal

例如:

#include <vector>
#include <algorithm>
#include <functional>

namespace datastructures {

  struct Foo;

  struct Rectangle {
    int width;
    int height;
  };

  bool operator<=(const Rectangle& lhs, const Rectangle& rhs){
    return lhs.width <= rhs.width;
  } // end namespace                                                                                                                                                                                                

  bool operator<=(const Foo&, const Foo&);

}

class Algorithm {
public:
  typedef datastructures::Rectangle Rectangle;
  void func1(int median);
private:
  std::vector<Rectangle> rectangles_;
};

// Algorithm.hpp                                                                                                                                                                                                    
void Algorithm::func1(int median){
  // this fails
  std::nth_element(rectangles_.begin(),
                   rectangles_.begin() + median, rectangles_.end(), datastructures::operator<=);
  // this works
  std::nth_element(rectangles_.begin(),
                   rectangles_.begin() + median, rectangles_.end(), std::less_equal<Rectangle>());

}

您还必须将比较函数声明为inline,否则您将在链接步骤中获得多个定义。

答案 1 :(得分:0)

更改:

private:
   std::vector<Rectangle> rectangles_;

到此:

private:
   std::vector<datastructures::Rectangle> rectangles_;

并在structures.hpp文件中添加一个额外的右括号(对于命名空间),允许我编译代码。您是否故意在structures.hpp

中省略了名称空间的右括号