Где я могу найти или как я могу создать элегантный механизм оболочки шаблона функции-члена C++, не требуя повышения?

StackOverflow https://stackoverflow.com/questions/991640

Вопрос

Я хочу иметь возможность создавать шаблоны класса для функции-члена без необходимости повторять аргументы функции-члена, т. е. автоматически выводить их.Я знаю, как это сделать, если назову класс в зависимости от того, сколько аргументов принимает функция, но я хочу получить и это.

Что-то вроде этого, хотя это не работает (по крайней мере, в MSVC 2008 sp1, который является моим целевым компилятором):

class Foo {
  void func0();
  int func2(char *, float);
};

template<typename T> class Wrapper;

// specialize for zero-argument void func
template<typename Host, void (Host::*Func)()> class Wrapper<Func> : public Base {
  ... specialization goes here ...
};

// specialize for two-argument value func
template<typename Host, typename Ret, typename Arg0, typename Arg1, Ret (Host::*Func)(Arg0, Arg1)> class Wrapper<Func> : public Base {
  ... specialization goes here ...
};

Через «Базу» я могу обрабатывать их полиморфно.В конце концов, я хочу использовать это для создания простого синтаксиса-оболочки для языка сценариев:

WrapClass<Bar> wrap(
  MemberFunction<&Bar::func0>("func0") +
  MemberFunction<&Bar::func2>("func2")
  );

Однако это не работает:синтаксис специализации неправильный, поскольку вы не можете сопоставить указатель функции с аргументом имени типа.

Это было полезно?

Решение

Я считаю, что вам нужно будет использовать подход с использованием признаков, наиболее распространенной библиотекой которого является boost, но если вы хотите избежать повышения, не будет чрезвычайно сложно реализовать свою собственную, если вы ограничите область реализации просто указатель на функции-члены и характеристики тех, которые вам нужны (современный дизайн на С++ отличная книга, объясняющая теорию).Вот как бы я сделал это с помощью function_traits и Enable_if Boost.

Вы можете использовать общий аргумент шаблона, Enable_if для указателей на функции, а затем использовать типы функций (или свойства типов), чтобы получить необходимую информацию:

#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/is_member_pointer.hpp>

template<typename T, class Enable = void> class Wrapper;

/* other specializations... */

// For member functions:
template <class T>
class Wrapper<T, typename enable_if<is_member_pointer<T> >::type>
{ /* function_arity<T>::value has the number of arguments */ };

Видеть этот и этот

Другие советы

Стандартная библиотека C++ предоставляет mem_fun_ref какой тип работает так, как вы хотите, хотя он работает только для нулевых и унарных функций.Конечно, вы можете использовать структуру со всеми параметрами в качестве одного аргумента.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top