简体   繁体   中英

compile error about template deduction on c++

#include <iostream>

template <int N>                                                                         
class X {
public:
  using I = int;                                                                         
  void f(I i) {
    std::cout << "i: " << i << std::endl;
  }
};

template <int N>
void fppm(void (X<N>::*p)(typename X<N>::I)) {
  p(0);
}

int main() {
  fppm(&X<33>::f); 
  return 0;
}

I just don't understand the compile error message of the code.

error: called object type 'void (X<33>::*)(typename X<33>::I)' is not a function or function pointer
 p(0);

I think p is a function which returns void and takes int as its argument. But apparently, it's not. Could somebody give me clue?

Since p is a pointer to a nonstatic member function, you need an instance to call it with. Thus, first instantiate an object of X<33> in main:

int main() {
  X<33> x;
  fppm(x, &X<33>::f); // <-- Signature changed below to accept an instance

Then in your function, change the code to accept an instance of X<N> and call the member function for it:

template <int N>
void fppm(X<N> instance, void (X<N>::*p)(typename X<N>::I)) {
  (instance.*p)(0);
}

The syntax may look ugly but the low precedence of the pointer to member operator requires the need for the parentheses.

As denoted in the comments already, p is a pointer to member function, but you call it like a static function ( p(0); ). You need a concrete object to call p on:

X<N> x;
(x.*p)(0);
// or:
X<N>* xx = new X<N>();
(xx->*p)(0);
delete xx;

Be aware that the .* / ->* operators have lower precedence than the function call operator, thus you need the parentheses.

Side note: Above is for better illustration, modern C++ might use auto keyword and smart pointers instead, which could look like this:

auto x = std::make_unique<X<N>>();
(x.get()->*p)(0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM