Как я могу эффективно использовать определение структуры, включая операторы из другого исходного файла?

У меня есть проект, который состоит из нескольких подмодулей. Поскольку у меня есть некоторые структуры, такие как, например, 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>)’ 

Почему он не знает operator<= из моего файла заголовка структуры данных?

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 в противном случае вы получите несколько определений в шаге ссылки.

Изменение:

private:
   std::vector<Rectangle> rectangles_;

к этому:

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

а также добавление дополнительной закрывающей скобки в structures.hpp файл (для пространства имен), позволяет мне хорошо скомпилировать код. Вы сознательно не указали закрывающую скобку для пространства имен в structures.hpp?

Другие вопросы по тегам