std::function для шаблонных функций

349
12 ноября 2017, 17:11

Есть такой класс.

#include <functional>
using namespace std::placeholders;
template<class T>
class test_class
{
public:
    template<class T>
    void value(T v)
    {
        std::function<T(double, int)> func = std::bind(&test_class::test, this, _1, _2, v);
        func(45.6, 8);
    }
    template<class T>
    T test(double d, int i, T t)
    {
        return T();
    }
};
int main()
{
    test_class<int> ts;
    int a = 45;
    ts.value(a);
    return 0;
}

Имеются ошибки компиляции:

1) "std::bind": не найдена соответствующая перегруженная функция;

2) std::_Binder<std::_Unforced,_Fx,_Types...> std::bind(_Fx &&,_Types &&...): не удается составить аргумент шаблон для "_Fx".

Как правильно составить конструкцию?

P. S.: код не несет смысла, просто пример.

Answer 1

У меня Visual Studio 2017 скомпилировала так:

std::function<T(double, int)> func = std::bind(&test_class::test<T>, this, _1, _2, v);

Более строгий gcc заметил совпадение имён внешнего и внутреннего шаблонных параметров и потребовал ещё убрать template<class T> у внешнего класса и в объявлении test_class<int> ts; убрать шаблонный параметр.

(Или можно убрать template<class T> у функций-членов, тогда строчка с std::bind пройдёт и в вашем варианте.)

Корень проблемы, насколько я понимаю, в том, что std::bind требуется на вход функция (точнее — callable object), а не шаблон функции. А вы передаёте именно шаблон.

Answer 2

Во-первых, очевидная грубая ошибка

template<class T>
class test_class
{
public:
    template<class T>
    void value(T v)
    ...

Имя параметра внешнего шаблона запрещается переиспользовать в качестве имени параметра шаблона-члена. Так что внутренний параметр придется переименовать

template<class T>
class test_class
{
public:
    template<class U>
    void value(U v)
    ...
    template<class U>
    U test(double d, int i, U t)
    ...

Во-вторых, в реализации функции value упоминается шаблон test_class::test без указания шаблонных аргументов. Это ни в какие ворота не лезет. Для шаблона test_class аргумент можно не указывать и тогда test_class в этом контексте будет расцениваться как test_class<T>. Однако для шаблона test указание аргумента обязательно. Если я правильно понимаю ваши намерения это должен быть U

template<class U>
void value(U v)
{
    std::function<U(double, int)> func = std::bind(&test_class::test<U>, this, _1, _2, v);
    func(45.6, 8);
}
READ ALSO
Возвращение массива функцией

Возвращение массива функцией

Есть кодВ функции double f(double x[], int n) делается вычисление нескольких функций с несколькими переменными

289
Как сделать шрифт в Qpainter больше

Как сделать шрифт в Qpainter больше

Делаю генератор мемов и хочу сделать нормальный текст а шрифт получается маленьким как его сделать большим?Я добавил spinBoX и собираюсь в нем...

335
События jQuery( анимация бургер меню)

События jQuery( анимация бургер меню)

Есть код, который плавно меняет значение свойства, нужно чтобы при втором нажатии на элемент значение менялось !!! вот моя попытка, но получеться...

288
Русские буквы в комментариях CSS

Русские буквы в комментариях CSS

Заливаю лабу в gitlab, но там не отображаются комментарии русскими буквами в CSS файле, в html файле все нормальноКак сделать чтобы русские буквы...

395