Подтвердить что ты не робот

С++ functor и функциональные шаблоны

рассмотрим этот простой и бессмысленный код.

#include <iostream>

struct A {
    template<int N>
    void test() {
        std::cout << N << std::endl;
    }
};

int main() {
    A a;
    a.test<1>();
}

Это очень простой пример шаблона функции. Что если, однако, я хотел бы заменить A::test на перегруженный operator(), чтобы сделать его функтором?

#include <iostream>

struct A {
    template<int N>
    void operator()() {
        std::cout << N << std::endl;
    }
};

int main() {
    A a;
    a<1>(); // <-- error, how do I do this?
}

Конечно, если operator() взял параметры, зависящие от шаблона, компилятор мог бы вывести шаблон. Но я просто не могу понять правильный синтаксис, чтобы указать параметры шаблона с помощью безпараметрического функтора.

Есть ли правильный способ сделать это?

Очевидно, что этот код будет работать, поскольку он обходит синтаксис функтора:

a.operator()<1>();

но этот вид побеждает цель его функционала: -P.

4b9b3361

Ответ 1

Нет другого "прямого" способа, который я знаю, кроме:

 a.operator()<1>();

синтаксис. Если вы открыты для изменения кода, перемещение параметра шаблона в класс будет работать или с помощью (boost | tr1):: bind, чтобы создать объект (boost | tr1):: function.

Ответ 2

Вы можете звонить только

a.operator()<1>();

но это не будет использовать функтор. Функторам нужен оператор non template(), поскольку они должны быть вызваны как varname(), и это не будет работать с вашим кодом.

Чтобы сделать его реальным функтором, измените свой код на класс шаблона (функторы - это классы):

#include <iostream>

template<int N>
struct A {
    void operator()() {
        std::cout << N << std::endl;
    }
};

int main() {
    A<1> a;
    a();
}

Ответ 3

Вы пытаетесь передать параметр шаблона экземпляру объекта, который, насколько мне известно, не разрешен. Вы можете передавать только параметры шаблонов в функции шаблона или объекты шаблона.

a.test < 1 > (); и a.оператор() < 1 > (); потому что они служат в качестве функций шаблона.

Используйте boost:: bind (проверьте библиотеки ускорения), чтобы исправить это.

struct A {
    void operator()(int n) {
        std::cout << n << std::endl;
    }
};

int main(int argc, char* argv[]) {
    A a;
    boost::function<void()> f = boost::bind<void>(a, 1);
    f(); // prints 1

    return 0;
}

И вам даже не нужно возиться с шаблонами!

Ответ 4

Ты застрял. Вы считали что-то вроде

struct A {
    template<int N>
    struct B
    {
        void operator()()
        { std::cout << N << std::endl; }
    };

    template<int N>
    B<N> functor() {return B<N>();}
};

int main()
{
    A a;
    a.functor<1>()();
}

Ответ 5

Нет, нет. Как вы сказали, вам нужно либо явно вызвать оператор (который побеждает цель), либо аргументы шаблона должны быть выведены компилятором.