Указатель на член в качестве аргумента шаблона

Я использую Visual C ++ 2012. Я хочу параметризовать функцию шаблона с указателем на другую функцию. Все это прекрасно работает вне класса:

int add(int a, int b) {
return a + b;
}
typedef int (*func)(int a, int b);
template<func F> int do_it(int a, int b) {
return F(a, b);
}
int foo(int a, int b) {
return do_it<add>(a, b);
}

Visual C ++ 2012 прекрасно компилирует и оптимизирует это.

Теперь я помещаю его в класс и настраиваю для указателя на член:

struct S {
int add(int a, int b) {
return a + b;
}
typedef int (S::*func)(int a, int b);
template<func F> int do_it(int a, int b) {
return F(a, b);     // <-- here be error!
}
int foo(int a, int b) {
return do_it<&S::add>(a, b);
}
};
S s;

int bar(int a, int b) {
return s.foo(a, b);
}

Но это дает мне ошибку компилятора:

Microsoft (R) C/C++ Optimizing Compiler Version 17.00.51106.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

x2.cpp
x2.cpp(7) : error C2064: term does not evaluate to a function taking 2 arguments
x2.cpp(10) : see reference to function template instantiation 'int S::do_it<int S::add(int,int)>(int,int)' being compiled

Есть идеи почему и как это исправить?

2

Решение

Синтаксис для указателей на члены все еще применяется. Вы должны написать:

typedef int (S::*func)(int a, int b);
template<func F> int do_it(int a, int b) {
return (this->*F)(a, b);
}

Использование указателя на член всегда требует привязки объекта к нему — здесь имеет смысл вызвать указатель на this,

4

Другие решения

Указатели на функции-члены должны вызываться для объекта; в отличие от обычного вызова функции-члена, this должен быть указан явно:

(this->*F)(a,b);

Хотя, если функция не нуждается в доступе thisвозможно, он должен быть статическим (или не являющимся членом), указанным обычным указателем на функцию.

2

Похоже, вам просто нужно вызвать указатель на функцию-член объекта:

template<func F> int do_it(int a, int b) {
return (this->*F)(a, b);
}

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

1

Вы должны предоставить объект при вызове функции указателя на meber:

(this->*F)(a, b);
1

Еще один момент: напишите ваш «do_it» в более общем виде

template<class F> int do_it(F f, int a, int b) {
return f(a, b);        }

Теперь вы можете передать ему любую функцию из двух целых чисел:

int mul(int a, int b) { return a*b ; }
S s;
s.do_it(mul,2,3);

Когда вы намереваетесь использовать его внутри своего класса с функцией-членом, просто свяжите это с этим. Используя boost :: bind,

   int foo(int a, int b) {
return do_it( boost::bind(&S::add,this,_1,_2),a,b)  ;
0
По вопросам рекламы [email protected]