c ++ - 专门少于<>和更大的<>

时间:2016-10-24 23:46:51

标签: c++ templates functor

我正在尝试实现一个AVL-List-Container,并希望程序员可以通过模板将一个参数传递给容器,以便影响排序顺序。

STL容器(set,sort等)允许使用带有重载()-operator作为参数的结构less<>greater<>。 我没有设法将仿函数传递给我的容器。

测试场景是:

#include <iostream>
#include <functional>

using namespace std;

namespace TEST_SPACE {

template< typename T, typename COMP_FUNC = ::std::less<T> >
class cTst {

  T data;
  T* data_ptr;

public:
  template< typename U = T >
  bool get_min_00( ) { }

  template< typename V,  typename FUNC = COMP_FUNC, bool dummy = false>
  bool get_min_01( V a, V b  ) {
  return (*FUNC) ( a, b );
  }
};  // class cTst
}   // namespace TEST_SPACE

int main() {

TEST_SPACE::cTst< int > obj_00;
obj_00.get_min_00< int >();     // working
obj_00.get_min_01< int > ( 2, 3 );  // working
obj_00.get_min_01< int,  ::std::greater<int>() > ( 2, 3 );
return 0;
}

我正在使用gcc版本4.9.2(Debian 4.9.2-10)。编译器抱怨:

gcc -Wall -c -O2 -std=c++11 -fpic _tst-04.cpp 
_tst-04.cpp: In member function ‘bool TEST_SPACE::cTst<T, COMP_FUNC>::get_min_01(V, V)’:
_tst-04.cpp:31:20: error: expected primary-expression before ‘)’ token
  return (*FUNC) ( a, b );
        ^
_tst-04.cpp: In instantiation of ‘bool TEST_SPACE::cTst<T, COMP_FUNC>::get_min_01(V, V) [with V = int; FUNC = std::less<int>; bool dummy = false; T = int; COMP_FUNC = std::less<int>]’:
_tst-04.cpp:62:37:   required from here    

我在网上搜索,发现没有合适/可行的解决方案来解决这个问题。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

模板的参数必须是&#34; typename COMP_FUNC&#34;,类型/类。

obj_00.get_min_01< int,  ::std::greater<int>() > ( 2, 3 );

&#34; ::的std ::更大()&#34;不是类型,它是构造函数调用,在这里。这应该是:

obj_00.get_min_01< int,  ::std::greater<int> > ( 2, 3 );

答案 1 :(得分:0)

我找到了解决问题的临时解决方案:

#include <iostream>
#include <functional>
#include <string>

using namespace std;


template <typename T, typename CMP = std::less<T>, typename A1, typename A2>
bool getOrder_05( const A1&& a, const A2&& b, CMP func =  CMP( ) )
{
  return (func)( std::forward<A1>(a), std::forward<A2>(b) );
  //return new T(std::forward<A1>(a1), std::forward<A2>(a2));
}

class cStructure {

public:
cStructure( int x, std::string str = "" ) : m_int_value( x ) , m_str_value( str ) {}

friend std::less<cStructure >;
friend std::greater<cStructure >;
friend std::less<cStructure * >;

int GetIntValue() { return this->m_int_value; } ;
std::string GetStringValue() { return this->m_str_value; } ;

protected:
int m_int_value = 0;
std::string m_str_value;



};  // cStructure

namespace std {
template<>
struct less<cStructure> : public binary_function <cStructure , cStructure , bool>
{
public:

    bool operator()(const cStructure &a, const cStructure & b ) const
    {
    return a.m_int_value < b.m_int_value ;
    }

};
}

namespace std {
template<>
struct greater<cStructure> : public binary_function <cStructure , cStructure , bool>
{
public:

    bool operator()(const cStructure &a, const cStructure & b ) const
    {
    return a.m_int_value > b.m_int_value ;
    }

};
}

namespace std {
template<>
struct less<cStructure *> : public binary_function <cStructure *, cStructure *, bool>
{
public:

    bool operator()(const cStructure * a, const cStructure * b ) const
    {
    return a->m_int_value < b->m_int_value ;
    }


};  // less<cStructure *>
}

namespace std {
class lessByStringValue : public binary_function < cStructure, cStructure, bool >
{
public:

    bool operator()( cStructure * a, cStructure  * b ) const
    {
    return a->GetStringValue( ) < b->GetStringValue( ) ;
    }

};  // lessByStringValue<cStructure *>
}



int main()
{

  int set_value_00 = 20;

cStructure obj_00 = cStructure( 11, "Pizza Mare" );
cStructure obj_01 = cStructure(  7, "Ciabatta" );

cStructure *obj_02 = new cStructure( 14, "Pizza Margeritha");
cStructure *obj_03 = new cStructure(  8, "Cannelloni");
cStructure *obj_04 = new cStructure(  5, "Spagetthi");
cStructure *obj_05 = new cStructure( 10, "Pizza Napoli" );
cStructure *obj_06 = new cStructure( 12, "Pizza Funghi" );

bool value_05a = getOrder_05<cStructure>( obj_00, obj_01 );
bool value_05b = getOrder_05<cStructure * >( obj_02, obj_03 );
bool value_05c = getOrder_05<cStructure * >( &obj_00, obj_03 );
bool value_05d = getOrder_05<int>( 2, int(15) );
bool value_05e = getOrder_05<int, std::less<int> >( 2, int(15) );
bool value_05f = getOrder_05<cStructure *, std::less<cStructure *> >( &obj_00, obj_03 );
bool value_05g = getOrder_05<cStructure *, std::lessByStringValue >( &obj_00, obj_03 );


delete obj_02;
delete obj_03;
delete obj_04;
delete obj_05;
delete obj_06;


return 1;

}

这是一个临时解决方案,因为它并不完全符合我的要求:模板

template <typename T, typename CMP = std::less<T>, typename A1, typename A2>
bool getOrder_05( const A1&& a, const A2&& b, CMP func =  CMP( ) )
{
  return (func)( std::forward<A1>(a), std::forward<A2>(b) );
  //return new T(std::forward<A1>(a1), std::forward<A2>(a2));
}

期望类型的地址而不是() - 运算符的地址。因此我必须写

bool value_05f = getOrder_05<cStructure *, std::less<cStructure *> >( &obj_00, obj_03 );
bool value_05g = getOrder_05<cStructure *, std::lessByStringValue >( &obj_00, obj_03 );

而不是

bool value_05f = getOrder_05<cStructure *, std::less<cStructure *>() >( &obj_00, obj_03 );
bool value_05g = getOrder_05<cStructure *, std::lessByStringValue() >( &obj_00, obj_03 );

也许有人知道另一种方法吗?