我正在尝试实现一个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
我在网上搜索,发现没有合适/可行的解决方案来解决这个问题。有什么想法吗?
答案 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 );
也许有人知道另一种方法吗?