Я получаю очень странную ошибку в очень простом коде, который не могу исправить.
Я определил следующий функциональный объект:
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
пространство (с необходимыми операторами, …).
Я ожидаю получить l2-норму точки p
(создан как Point<5> p
например) используя 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>&’
Я почти уверен, что делаю очень глупую ошибку, но не могу узнать где!
Постскриптум Как побочный вопрос, было бы намного лучше, если бы я мог сказать L2Norm(p)
только и компилятор обнаруживает параметр шаблона из p
но, насколько мне известно, это невозможно. Я прав?
Вам нужно создать экземпляр и вызвать его оператор ()
, В настоящее время вы пытаетесь вызвать несуществующий конвертирующий конструктор.
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 { .... }
};
Как уже ответил @ 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. В boost это будет, если вы предоставите соответствующие определения, а в 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.