urps
urps

Reputation: 366

Using functors without default constructors for stl containers

I would like to use my own comparator for std::set, which needs a parameter to be passed to its constructor:

template <class T = double> class EpsCompare {
  public:
    EpsCompare(T input_eps) : _eps(input_eps) {};
    bool operator() (const T & element1, const T & element2) const {
       return ( round(element1*_eps) < round(element2*_eps) );
    }
    T _eps;
};

How do I pass this to the declaration of my set data type? I would like to do something like this:

std::set<double, EpsCompare<double>(1e-5)> myEpsSet;

This does not compile, so how else can it be done?

Upvotes: 3

Views: 909

Answers (3)

Slava
Slava

Reputation: 44288

If you want to pass eps as parameter to std::set you have to make it part of template. You cannot use double as template parameter, so one of the solution to have power as template parameter:

template <class T, int power > class EpsCompare {
  public:
    EpsCompare() { eps = pow( 10, power ); }
    bool operator() (const T & element1, const T & element2) const {
       return ( round(element1*eps) < round(element2*eps) );
    }
  private:
       T eps;
};

std::set<double, EpsCompare<double,-5>> myEpsSet;

If you want to pass eps as parameter to EpsCompare constructor, you make it runtime so you cannot use it in template and pass your comparator to std::set:

std::set<double,EpsCompare<double>> myEpsSet( EpsCompare<double>( 1e-5 ) );

will be sufficient.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311146

Something as

#include <iostream>
#include <set>

template <class T = double> class EpsCompare {
  public:
    EpsCompare(T input_eps) : _eps(input_eps) {};
    bool operator() (const T & element1, const T & element2) const {
       return ( round(element1*_eps) < round(element2*_eps) );
    }
    T _eps;
};


int main() 
{
    std::set<double, EpsCompare<double>> myEpsSet(EpsCompare<double>(1e-5) );

    return 0;
}

Upvotes: 1

R Sahu
R Sahu

Reputation: 206737

std::set<double, EpsCompare<> > myEpsSet(EpsCompare<>(1e-5));

or

std::set<double, EpsCompare<double> > myEpsSet(EpsCompare<double>(1e-5));

Upvotes: 5

Related Questions