我在一个非常简单的代码上遇到了一个非常奇怪的错误,我无法修复。
我定义了以下函数对象:
template<const size_t n> class L2Norm {
public:
double operator()(const Point<n>& p) {
/* computes the L2-norm of the point P ... */
}
double operator()(const Point<n>& p,
const Point<n>& q) {
return L2Norm<n>(p-q);
}
};
此前,Point<n>
类已明确定义,以便在n
- 维空间(带有必需的运算符,...)中存储点的n
坐标。
我希望使用p
获得点Point<5> p
的l2范数(例如,创建为L2Norm<5>(p)
)。但这给了我以下错误:
no matching function for call to ‘L2Norm<5ul>::L2Norm(Point<5ul>&)’
note: candidates are: L2Norm<n>::L2Norm() [with long unsigned int n = 5ul]
note: candidate expects 0 arguments, 1 provided
note: L2Norm<5ul>::L2Norm(const L2Norm<5ul>&)
note: no known conversion for argument 1 from ‘Point<5ul>’ to ‘const L2Norm<5ul>&’
我很确定我犯的是一个非常愚蠢的错误,但我无法找到答案!
P.S。作为一个附带问题,如果我只能说L2Norm(p)
并且编译器从p
检测到模板参数会更好,但据我所知,这是不可能的。我是对的吗?
答案 0 :(得分:7)
您需要创建一个实例并调用其运算符()
。目前,您正在尝试调用不存在的转换构造函数。
return L2Norm<n>()(p-q); // C++03 and C++11
// ^^
或
return L2Norm<n>{}(p-q); // c++11
// ^^
顺便说一下,您可能也想调用操作符const
,因为调用它们不太可能导致实例的可观察状态发生更改:
template<const size_t n> class L2Norm
{
public:
double operator()(const Point<n>& p) const { .... }
double operator()(const Point<n>& p, const Point<n>& q) const { .... }
};
答案 1 :(得分:2)
正如@ juanchopanza已经回答的那样,你必须先创建对象:
L2Norm<5>()(p-q);
现在,您甚至可以获得:
L2Norm()(p-q)
使用所谓的“多态函数对象”。通过使用模板operator()
创建一个简单的类类型:
class L2Norm {
public:
template<const size_t n>
double operator()(const Point<n>& p) const {
/* computes the L2-norm of the point P ... */
}
template<const size_t n>
double operator()(const Point<n>& p,
const Point<n>& q) const {
return operator()(p-q);
}
};
缺点是你不能使它成为C ++ 03的自适应二进制函数,所以它不适用于某些C ++ 03算法。如果你提供了适当的定义,那么在C ++ 11中,由于使用decltype
,它应该被处理。
使用这种技术,可以消除多余的()
:
class {
public:
template<const size_t n>
double operator()(const Point<n>& p) const {
/* computes the L2-norm of the point P ... */
}
template<const size_t n>
double operator()(const Point<n>& p,
const Point<n>& q) const {
return operator()(p-q);
}
} L2Norm;
L2norm(p-q); // Uses the object L2Norm, which has an unnamed type.