Я хочу создать прокси для функций-членов и операторов.Они должны иметь одинаковые возвращаемый тип и параметры и должны подходить для нескольких классов, которые задаются как параметры шаблона.Даже если у класса нет конкретной функции-члена или оператора, я хочу, чтобы он компилировался, а не с ошибкой, по сути, с SFINAE.Если X
имеет метод f()
, а Y
не имеет метода с именем f
, мне нужно Proxy<X>
, чтобы иметь также f()
, который вызывает X::f()
, и мне нужно Proxy<Y>
дляскомпилируйте и создайте его без проблем.
Извлечение возвращаемого типа из известной функции больше не является проблемой после моего предыдущего вопроса .Однако, если такая функция отсутствует, она завершается ошибкой.
Я уже знаю несколько приемов метапрограммирования шаблонов, чтобы определить, существует ли данная функция, и включить определенную функцию, если они есть, однако все они работают только наимена произвольных функций вместо произвольных, что сильно ограничивает их использование в этом случае, поскольку мне нужна одна и та же конструкция для нескольких функций.
Мне нужно только проверить, существует ли какая-либо функция с данным именем, если они перегруженыварианты, которые мне не нужно проверять, существует ли конкретный, автоматическое вычитание шаблона решает это (или я так надеюсь)
Мой текущий код выглядит так:
template <class T>
class Proxy
{
// using my resultof solution
template <class... Args>
resultof(T::f, Args...) f (Args... x)
{
return x.f(x...);
}
// using another return type extraction solution
template <class... Args>
typeof(T::f(std::declval<Args>()...)) f (Args... x)
{
return x.f(x...);
}
T x;
};
, который должен компилироваться дажеесли T не имеет функции с именем f.К сожалению, обе версии не работают с ошибкой.
Реализация результата:
#define resultof(f, ...) typeof(Param<__VA_ARGS__>::Func(f))
template <class... Args>
class Param
{
public:
template <class R>
static R Func (R (*) (Args...));
template <class R, class C>
static R Func (R (C::*) (Args...));
template <class R, class C>
static R Func (R (C::*) (Args...) const);
};