【问题标题】:How can I effectively use a struct definition including operators from another source file?如何有效地使用包含来自另一个源文件的运算符的结构定义?
【发布时间】:2013-10-10 13:08:28
【问题描述】:

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

结构.hpp

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


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

算法.hpp

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

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

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

算法.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&lt;=

【问题讨论】:

    标签: c++ struct namespaces operators


    【解决方案1】:

    错误是由于:

    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,否则您将在链接步骤中获得多个定义。

    【讨论】:

    • 谢谢谢谢谢谢!! less_equal 解决方案有效!!
    • 别忘了点赞有用的答案并接受正确的答案 ;-)
    • 我投了赞成票,但我的声望分数太低了……抱歉!但至少我可以接受这个答案!
    【解决方案2】:

    变化:

    private:
       std::vector<Rectangle> rectangles_;
    

    到这里:

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

    并且还在structures.hpp 文件中添加一个额外的右大括号(用于命名空间),让我可以很好地编译代码。您是否故意省略了 structures.hpp 中命名空间的右大括号?

    【讨论】:

    • 不,抱歉,在复制和编辑我的代码时括号丢失了。
    • 但是由于我有嵌套的命名空间,不像我上面的简化示例,我希望使用缩短的 typedef Rectangle。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多