FunctoidsInCpp can be modified to use the concepts defined in ConceptCpp in place of the Sig structure to determine the return type. This code has been tested using ConceptGcc. Here are two versions of the same code, one without and one with concepts. Note that the code is not complete, e.g. both versions call through Curryable2Helper to resolve overloading of the operator() with two arguments. This call returns the type defined by the appropriate concept map. One advantage of doing it in this way is that the concept maps are reusable with different classes, rather than defined within a particular class template. -- JohnFletcher ---- '''Original Code''' Version of the FunctoidsInCpp code for a two parameter polymorphic functoid not using ConceptCpp. template class Full2 : public Smart''''''Functoid2 { F f; public: Full2() : f() {} Full2( const F& ff ) : f(ff) {} template struct Sig : public Fun''''''Type::Arg1Type, typename F::template Sig::Arg2Type, typename RT::Result''''''Type> {}; template struct Sig : public Fun''''''Type > > {}; template struct Sig : public Fun''''''Type > > {}; template struct Sig : public Fun''''''Type > > {}; template inline typename Sig::Result''''''Type operator()( const X& x ) const { return makeFull1( impl::binder1of2(f,x) ); } template inline typename Sig::Result''''''Type operator()( const X& x, const Y& y ) const { // need partial specialization, so defer to a class helper return impl::Curryable2Helper::Result''''''Type,F,X,Y>::go(f,x,y); } }; ---- '''The same code using concepts.''' auto concept Const''''''Callable2 { typename result_type; requires Copy''''''Constructible; result_type operator()(const F&, const X&, const Y& y); }; /* These concept maps are the equivalent of the different Sig definitions. */ template concept_map Const''''''Callable2 { typedef Full1 > result_type; }; template concept_map Const''''''Callable2 { typedef Full1 > result_type; }; template concept_map ConstCallable2 { typedef Full1 > result_type; }; template class Full2 : public Smart''''''Functoid2 { F f; public: Full2() : f() {} Full2( const F& ff ) : f(ff) {} template inline Const''''''Callable2::result_type operator()( const X& x ) const { return makeFull1( impl::binder1of2(f,x) ); } template inline Const''''''Callable2::result_type operator()( const X& x, const Y& y ) const { // need partial specialization, so defer to a class helper return impl::Curryable2Helper::result_type,F,X,Y>::go(f,x,y); } }; ---- '''Example of usage.''' This is the code within FC++(FunctoidsInCpp) which enables code using e.g. the FC++ object '''minus''' to handle calls such as minus(_,1)(2); // minus(_,1) returns a function which needs another argument. minus(2,_)(1); // minus(2,_) returns a function which needs another argument. which need to be distinguished at compile time from minus(2,1); // returns a result where the _ character is an object of type Auto''''''Curry''''''Type. Both versions of the code use the type of the argument to guide the selection of the return type from the two argument call. The actual return types are constructed in template specialisations of Curryable2Helper which are not shown here. They are the same whether or not concepts are used. Single parameter calls can also be used minus(2)(1); // minus(2) returns a function which needs another argument. In this case the concept map has one template parameter and the other is supplied by the default type Nothing. -- JohnFletcher ---- CategoryCpp CategoryCppTemplates CategoryFunctionalProgramming CategoryConcepts