Вывод параметра шаблона из шаблонного нетипичного аргумента шаблона - PullRequest
1 голос
/ 28 мая 2019

У меня есть следующий typedef:

template<typename G, typename T, typename R>
using my_func_type = typename R(T::*)(G, int) const;

Это функция-член, которой я часто пользуюсь, поэтому я играю с разными оболочками.Предпосылка заключается в том, что мне нужен объект, который реализует эти функции посредством общего вызова функции, чтобы я мог комбинировать их различными способами (в настоящее время я использую простой способ упаковки вызова в виде лямбды).

ОднакоДругой способ - передать эту функцию как параметр шаблона нетипичного типа (это улучшает мою производительность по сравнению с лямбда-решением, потому что я постоянно его оцениваю), а именно:

template<typename G, typename T, typename R, my_func_type<G, T, R> f>
struct MyWrapper
{
    MyWrapper(G g, T t) : g{ g }, t{ t } {}
    auto eval(int n) const
    {
        return (t.*f)(g, n);
    }

protected:
    G g;
    T t;
};

int main()
{
    AnObject g;
    TheCallingObject t;
    auto f = &TheCallingObject::callit;

    MyWrapper<AnObject, TheCallingObject, double, f> wrap(g, t)
}

Но это кажетсянемного избыточен, поэтому возможно ли выводить аргументы шаблона из f?

На полпути я нашел следующее решение:

template<auto f, typename G, typename T>
struct MyWrapper
{
    OpFuncDerivative(G g, T t) : g{ g }, t{ t } {}
    auto eval(int n) const
    {
        return (t.*f)(g, n);
    }

protected:
    G g;
    T t;
};

int main()
{
    AnObject g;
    TheCallingObject t;
    auto f = &TheCallingObject::callit;

    // it won't automatically deduce AnObject and TheCallingObject 
    // through the parameters to the constructor though!
    MyWrapper<f, AnObject, TheCallingObject> wrap(g, t) 
}

1 Ответ

1 голос
/ 28 мая 2019

Вы можете написать вспомогательную функцию:

template<typename G, typename T, auto f>
struct MyWrapper
{
    MyWrapper(G g, T t) : g{g}, t{t}
    {}

    auto eval(int n) const
    {
       return (t.*f)(g, n);
    }

protected:
    G g;
    T t;
};

template<auto f, typename G, typename T>
MyWrapper<G, T, f> make_wrapper(G g, T t)
{
    return {g, t};
}

, а затем используйте его так:

int main()
{
    AnObject g;
    TheCallingObject t;
    constexpr auto f = &TheCallingObject::callit;

    auto wrap = make_wrapper<f>(g, t);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...