Вы можете использовать метод JavaScript sort
с функцией обратного вызова:
function compareASC(homeA, homeB)
{
return parseFloat(homeA.price) - parseFloat(homeB.price);
}
function compareDESC(homeA, homeB)
{
return parseFloat(homeB.price) - parseFloat(homeA.price);
}
// Sort ASC
homes.sort(compareASC);
// Sort DESC
homes.sort(compareDESC);
Как выглядит заголовок С? Где-то источник C должен перечислять допустимые типы обратного вызова. Вы должны воспользоваться этой возможностью, чтобы иметь ряд макросов, которые генерируют прототипы для отдельных функций заглушки, с соответствующей последовательностью макросов в источнике C ++, генерирующим extern "C"
заглушки.
Что касается второго вопроса : Да, это работает, но typedef
не находится внутри шаблона. Я попытался поместить такой тип typedef внутри класса, но оказывается, что даже шаблоны классов не допускаются внутри extern "C"
. Таким образом, у вас может быть шаблон функции, но нет параметров зависимого типа.
Простое определение этой функции легко:
extern "C" typedef void ftype(int);
template<typename T>
static ftype f; // <- added "static" here
template< typename T >
void f(int q) {}
Aha, вариативные функции!
extern "C" typedef void ftype( int, ... );
template<typename T>
static ftype f;
template< typename T >
static void f( int z, ... ) {
va_list va;
va_start( va, z );
T v = va_arg( va, T );
va_end( va );
std::cout << v;
}
Вам действительно не нужно выводить тип, поскольку это всего лишь обратный вызов, поэтому вы можете передать это & f<int>
в код C, все обратные вызовы имеют один и тот же тип, и он может сделать определение типа во время выполнения и передать все он хочет через varargs.
... есть ли легкая работа для достижения моей первоначальной цели?
blockquote>вы можете приблизиться к ней с нескольких углов, в зависимости от того, как вы хотите настроить и объявить их.
четыре подхода, одно пространство имен демонстрирует каждый. «Тип», пожалуй, самый простой для вашего использования.
#include <stdio.h> // favored to reduce exports in later demonstration #define FUNC_NAME __PRETTY_FUNCTION__ // or __func__ or __FUNCTION__ or... extern "C" { /* C prototype */ typedef void ftype(int a); /* the c function all our functions are piped into */ void call(ftype* a); /* helper which serves as the implementation for our functions */ void print(int a, const char* const func); /* C definitions (used in namespace examples below) */ static void static_float(int a) { print(a, FUNC_NAME); } static void static_double(int a) { print(a, FUNC_NAME); } void extern_float(int a); void extern_float(int a) { print(a, FUNC_NAME); } void extern_double(int a); void extern_double(int a) { print(a, FUNC_NAME); } static void static_function_float(int a) { print(a, FUNC_NAME); } static void static_function_double(int a) { print(a, FUNC_NAME); } } /* << extern C */ namespace Extern { /** interface demonstrates C functions as template arguments */ template<ftype Fn> struct t_func { static ftype* Function() { return Fn; } }; template<typename T> struct bind; template<> struct bind<float> { typedef t_func<extern_float> F; }; template<> struct bind<double> { typedef t_func<extern_double> F; }; template<typename T> void Call(T a) { (void) a; call(bind<T>::F::Function()); } } /* << Extern */ namespace Static { /** interface demonstrates template types wrapping static C functions */ template<typename T> struct bind; template<> struct bind<float> { static ftype* F() { return static_float; } }; template<> struct bind<double> { static ftype* F() { return static_double; } }; template<typename T> void Call(T a) { (void) a; call(bind<T>::F()); } } /* << Static */ namespace Function { /** interface demonstrates template functions wrapping static C functions */ template<typename T> ftype* bind(); template<> ftype* bind<float> () { return static_function_float; } template<> ftype* bind<double> () { return static_function_double; } template<typename T> void Call(T a) { (void) a; call(bind<T> ()); } } /* << Function */ namespace Type { /** interface demonstrates template types implementing static functions. although gcc4.2 and clang both compile it, i'm uncertain that this is conforming. */ template<typename T> struct bind { static void F(int a); }; template<> void bind<float>::F(int a) { print(a, FUNC_NAME); } template<> void bind<double>::F(int a) { print(a, FUNC_NAME); } template<typename T> void Call(T a) { (void) a; call(bind<T>::F); } } /* << Type */ int main(int argc, const char * argv[]) { (void) argc; (void) argv; const float f(1.0f); const double d(5.0); Extern::Call(f); Extern::Call(d); Static::Call(f); Static::Call(d); Function::Call(f); Function::Call(d); Type::Call(f); Type::Call(d); return 0; } void call(ftype* a) { a(11); } void print(int a, const char* const func) { printf("%i: %s\n", a, func); }
выходы:
11: void extern_float(int) 11: void extern_double(int) 11: void static_float(int) 11: void static_double(int) 11: void static_function_float(int) 11: void static_function_double(int) 11: static void Type::bind<T>::F(int) [with T = float] 11: static void Type::bind<T>::F(int) [with T = double]
:
nm unstripped: 0000000100000daf s stub helpers 0000000100001048 D _NXArgc 0000000100001050 D _NXArgv 0000000100000bde T __ZN4Type4bindIdE1FEi 0000000100000bc0 T __ZN4Type4bindIfE1FEi 0000000100000d98 s __ZZ12extern_floatE19__PRETTY_FUNCTION__ 0000000100000c98 s __ZZ12static_floatE19__PRETTY_FUNCTION__ 0000000100000d80 s __ZZ13extern_doubleE19__PRETTY_FUNCTION__ 0000000100000cb0 s __ZZ13static_doubleE19__PRETTY_FUNCTION__ 0000000100000d60 s __ZZ21static_function_floatE19__PRETTY_FUNCTION__ 0000000100000d38 s __ZZ22static_function_doubleE19__PRETTY_FUNCTION__ 0000000100000cc8 s __ZZN4Type4bindIdE1FEiE19__PRETTY_FUNCTION__ 0000000100000d00 s __ZZN4Type4bindIfE1FEiE19__PRETTY_FUNCTION__ 0000000100001060 D ___progname 0000000100000000 A __mh_execute_header 0000000100001058 D _environ U _exit 0000000100000c00 T _extern_double 0000000100000b20 T _extern_float 0000000100000c20 T _main U _printf 0000000100000b60 t _static_double 0000000100000b40 t _static_float 0000000100000ba0 t _static_function_double 0000000100000b80 t _static_function_float U dyld_stub_binder 0000000100000ae0 T start nm stripped: 0000000100000000 A __mh_execute_header U _exit U _printf U dyld_stub_binder
извините, я не позаботясь о стандартах сегодня - надеюсь, что это поможет. удачи!
Я не знаю причину ограничения, но не можете ли вы использовать функцию обёртки extern "C"
, которая вызывает конкретный экземпляр шаблона, о котором вы заботитесь?
extern "C" { ... }
вместоextern "C" ...
, потому что последнее не позволяет объединить его сstatic
в одном объявлении. – Johannes Schaub - litb 8 April 2011 в 04:28static ftype f
может быть несоответствующим. Но в начале этого параграфа упоминаются имена, и в основном обсуждается видимость, поэтому он не может ссылаться на тип функции. – Potatoswatter 8 April 2011 в 06:11