关于c++上模板推导的编译错误
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;
}
就是代码的编译错误提示我看不懂
error: called object type 'void (X<33>::*)(typename X<33>::I)' is not a function or function pointer
p(0);
我认为 p 是一个函数,它 returns 无效并以 int
作为参数。但显然,事实并非如此。有人可以给我线索吗?
正如注释中已经指出的那样,p
是指向成员函数的指针,但您可以像静态函数一样调用它 (p(0);
)。您需要一个具体对象来调用 p
on:
X<N> x;
(x.*p)(0);
// or:
X<N>* xx = new X<N>();
(xx->*p)(0);
delete xx;
请注意,.*
/->*
运算符的优先级低于函数调用运算符,因此您需要 括号。
旁注:以上是为了更好地说明,现代 C++ 可能会使用 auto
关键字和智能指针,它可能看起来像这样:
auto x = std::make_unique<X<N>>();
(x.get()->*p)(0);
由于 p
是指向非静态成员函数的指针,您需要一个实例来调用它。于是,首先在main:
中实例化一个X<33>
的对象
int main() {
X<33> x;
fppm(x, &X<33>::f); // <-- Signature changed below to accept an instance
然后在您的函数中,更改代码以接受 X<N>
的实例并为其调用成员函数:
template <int N>
void fppm(X<N> instance, void (X<N>::*p)(typename X<N>::I)) {
(instance.*p)(0);
}
语法可能看起来很丑陋,但是指向成员运算符的指针的低优先级需要括号。
#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;
}
就是代码的编译错误提示我看不懂
error: called object type 'void (X<33>::*)(typename X<33>::I)' is not a function or function pointer
p(0);
我认为 p 是一个函数,它 returns 无效并以 int
作为参数。但显然,事实并非如此。有人可以给我线索吗?
正如注释中已经指出的那样,p
是指向成员函数的指针,但您可以像静态函数一样调用它 (p(0);
)。您需要一个具体对象来调用 p
on:
X<N> x;
(x.*p)(0);
// or:
X<N>* xx = new X<N>();
(xx->*p)(0);
delete xx;
请注意,.*
/->*
运算符的优先级低于函数调用运算符,因此您需要 括号。
旁注:以上是为了更好地说明,现代 C++ 可能会使用 auto
关键字和智能指针,它可能看起来像这样:
auto x = std::make_unique<X<N>>();
(x.get()->*p)(0);
由于 p
是指向非静态成员函数的指针,您需要一个实例来调用它。于是,首先在main:
X<33>
的对象
int main() {
X<33> x;
fppm(x, &X<33>::f); // <-- Signature changed below to accept an instance
然后在您的函数中,更改代码以接受 X<N>
的实例并为其调用成员函数:
template <int N>
void fppm(X<N> instance, void (X<N>::*p)(typename X<N>::I)) {
(instance.*p)(0);
}
语法可能看起来很丑陋,但是指向成员运算符的指针的低优先级需要括号。