0

I'm trying to compile someone else's c++ code to do MAFIA clustering. I have limited c++ experience. I'm running into issues when using the makefile.

It looks like its an issue with the number of arguments being passed to binary_function, but it appears to me that 3 arguments are being passed (and 3 arguments are expected). The number of brackets and parens also look correct. Is there something special about using ref<> in this context? I'm not quite sure why the 3 arguments are being seen as one.

#ifndef MAFIA_CDU_H_
#define MAFIA_CDU_H_

/** @file cdu.h a single (candidate) dense unit in MAFIA algorithm */

#include <functional>
#include <vector>

#include "ref.h"
#include "window.h"

using namespace std;

/** a coordinate of a single window for a single dimension */
struct dimpair_t
{
    dimpair_t(int dim, int win)
    {
        this->dim = dim;
        this->win = win;
    }
    bool operator==(const dimpair_t &dp2) const
    {
        return dim == dp2.dim && win == dp2.win;
    }
    bool operator!=(const dimpair_t &dp2) const
    {
        return !(*this == dp2);
    }
    /** the dimension number */
    int dim;
    /** the number of window inside a dimension */
    int win;
};

/** a single (candidate) dense unit */
class Cdu : public ref_object
{
    /** creates an empty CDU */
    Cdu() : npoints(0), flag(false) {}

public:
    /** creates a 1D CDU */
    Cdu(int dim, int win) : npoints(0), flag(false)
    {
        coords.push_back(dimpair_t(dim, win));
    }
    /** the dimensionality (length) of the CDU */
    inline int len() const { return coords.size(); }
    /** checks whether the CDU is the same as another one */
    bool operator==(const Cdu &cdu2) const;
    /** checks whether the CDU is distinct from another one */
    bool operator!=(const Cdu &cdu2) const { return !(*this == cdu2); }
    /** checks whether this CDU is 'less' than the other one. The less comparison
            is somewhat artificial, but ensures strict order on the set of all
            possible CDUs.
            CDU a is less than CDU b iff one of the following holds:
            - dimensionality of a is less than dimensionality of b
            - a and b are of the same dimensionality, but the vector of dimension
            numbers for a is lexicographically smaller than the vector of dimension
            numbers for b
            - a and b are of the same dimensionality, and their dimension number
            vectors are equal, but the corresponding window number vector for a is smaller
    */
    bool operator<(const Cdu &cdu2) const;
    /** gets the subsequence of the CDU by omitting one of the components 
            @param ic the component to omit
            @remarks the caller is responsible for deallocation of the returned value
     */
    Cdu *subsequence(int ic) const;
    /** checks whether the CDU can merge with another one */
    bool can_merge_with(const Cdu &cdu2);
    /** merge two units and create a third one; the new CDU is
      allocated in dynamic memory and is owned by the caller */
    Cdu *merge_with(const Cdu &cdu2);
    /** checks whether this unit is assimilated into another one, i.e. its set of
            coordinates is a subset of cdu2's set of coordinates */
    bool is_assimilated_into(const Cdu &cdu2) const;
    /** checks whether the CDU contains the point */
    template <class T>
    bool contains_point(const T *ps, int n, int d, int i, const vector<Window> &ws) const;
    /** counts the points inside the CDU (the naive way), also sets the point count */
    template <class T>
    int count_points_direct(const T *ps, int n, int d, const vector<Window> &ws);
    /** conts the points inside the CDU using bitmaps from windows, and also sets
            the point count */
    int count_points_bitmaps(int nwords, unsigned *bmps, const vector<Window> &ws);
    /** checks whether CDU is dense with respect to window thresholds */
    bool is_dense(const vector<Window> &ws) const;
    /** checks whether this DU shares a face with another one; 
            @notes it returns false if two DUs are the same
     */
    bool has_common_face_with(const Cdu &cdu2, const vector<Window> &ws) const;
    /** the coordinates of the dense unit, sorted by ascending dimension
      number */
    vector<dimpair_t> coords;
    /** number of points in the CDU */
    int npoints;
    /** the flag which is used for various purposes connected with CDUs; in
            particular, it can mark it as joined or already visited */
    bool flag;
};

/** the comparator for ref<Cdu>, so that we can put it into a set */
struct CduCmp : binary_function<ref<Cdu>, ref<Cdu>, bool>
{
    inline bool operator()(const ref(Cdu) & p, const ref(Cdu) & q) const
    {
        // TODO: handle the 0-pointer in some way
        return *p < *q;
    } // operator()
};    // CduCmp

#endif

Here is the error I am seeing.

In file included from src/cdu.cpp:7:0:
src/cdu.h:105:57: error: wrong number of template arguments (1, should be 3)
 struct CduCmp : binary_function<ref<Cdu>, ref<Cdu>, bool>
                                                         ^
In file included from /usr/include/c++/7/functional:49:0,
                 from src/cdu.h:6,
                 from src/cdu.cpp:7:
/usr/include/c++/7/bits/stl_function.h:118:12: note: provided for ‘template<clas                                                                                                                                                                                               s _Arg1, class _Arg2, class _Result> struct std::binary_function’
     struct binary_function
            ^~~~~~~~~~~~~~~
In file included from src/cdu.cpp:7:0:
src/cdu.h:107:43: error: ISO C++ forbids declaration of ‘ref’ with no type [-fpe                                                                                                                                                                                               rmissive]
     inline bool operator()(const ref(Cdu) & p, const ref(Cdu) & q) const
                                           ^
src/cdu.h:107:45: error: expected ‘,’ or ‘...’ before ‘p’
     inline bool operator()(const ref(Cdu) & p, const ref(Cdu) & q) const
                                             ^
src/cdu.h: In member function ‘bool CduCmp::operator()(const int (*)(Cdu)) cons                                                                                                                                                                                                ’:
src/cdu.h:110:17: error: ‘p’ was not declared in this scope
         return *p < *q;
                 ^
src/cdu.h:110:22: error: ‘q’ was not declared in this scope
         return *p < *q;
                      ^
In file included from src/mafia-solver.cpp:1:0:
src/cdu.h:105:57: error: wrong number of template arguments (1, should be 3)
 struct CduCmp : binary_function<ref<Cdu>, ref<Cdu>, bool>
                                                         ^
In file included from /usr/include/c++/7/functional:49:0,
                 from src/cdu.h:6,
                 from src/mafia-solver.cpp:1:
/usr/include/c++/7/bits/stl_function.h:118:12: note: provided for ‘template<clas                                                                                                                                                                                               s _Arg1, class _Arg2, class _Result> struct std::binary_function’
     struct binary_function
            ^~~~~~~~~~~~~~~
In file included from src/mafia-solver.cpp:1:0:
src/cdu.h:107:43: error: ISO C++ forbids declaration of ‘ref’ with no type [-fpe                                                                                                                                                                                               rmissive]
     inline bool operator()(const ref(Cdu) & p, const ref(Cdu) & q) const
                                           ^
src/cdu.h:107:45: error: expected ‘,’ or ‘...’ before ‘p’
     inline bool operator()(const ref(Cdu) & p, const ref(Cdu) & q) const
                                             ^
src/cdu.h: In member function ‘bool CduCmp::operator()(const int (*)(Cdu)) cons                                                                                                                                                                                                ’:
src/cdu.h:110:17: error: ‘p’ was not declared in this scope
         return *p < *q;
                 ^
src/cdu.h:110:22: error: ‘q’ was not declared in this scope
         return *p < *q;
                      ^
Keshinko
  • 318
  • 1
  • 11
  • Notice that [`std::binary_function`](https://en.cppreference.com/w/cpp/utility/functional/binary_function) is deprecated in C++11 and removed in C++17. – Jarod42 Jul 24 '19 at 22:34
  • 1
    The most glaring error is [using namespace std; in the header file](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice), which no experienced C++ developer would ever do, because it is fertile ground for spawning these kinds of mysterious compilation errors. Without a [mre], it's impossible to say anything more, except that, unfortunately, it looks like an experienced C++ developer will be needed to figure out what's broken in with the code. – Sam Varshavchik Jul 24 '19 at 22:38
  • Wonder if the reported error is not due to the latter error `const ref(Cdu) & p` which should be `const ref & p`. – Jarod42 Jul 24 '19 at 22:48
  • Replacing `using namespace std` with `std::...` got rid of those errors! But given the next round of errors it looks like I have my work cut out for me to get this to compile :) Thank you for the help! If you put it as a full answer I can accept it, but I'm curious as to why making this change would relate to the "wrong number of template arguments" error. – Keshinko Jul 25 '19 at 12:56

1 Answers1

1

In this function here, the syntax is wrong where you use ref(Cdu). Use the angle braces, not parenthesis.

    inline bool operator()(const ref(Cdu) & p, const ref(Cdu) & q) const
    {
        // TODO: handle the 0-pointer in some way
        return *p < *q;
    } // operator()

Corrected version:

    inline bool operator()(const ref<Cdu> & p, const ref<Cdu> & q) const
    {
        // TODO: handle the 0-pointer in some way
        return *p < *q;
    } // operator()
Alecto Irene Perez
  • 10,321
  • 23
  • 46