Я хочу получить определение для pow2C следующим образом. Но мой компилятор показывает, что (__tmpDouble__) уже определено. Пожалуйста, помогите мне определить это.
#ifndef pow2C
double __tmpDouble__;
#define pow2C(a) ((__tmpDouble__=(a))*(__tmpDouble__))
#endif
.
.
.
inline double calculateDistance(double *x, double *y, int NDims)
{
double d = 0;
for (int i = 0; i < NDims; i++)
// it is faster to calculate the difference once
d += pow2C(x[i] - y[i]);
return sqrt(d);
}
Я хочу вычислить x [i] -y [i] только один раз, сохранить его в переменной и использовать.
Вы уже рассчитываете только один раз. Это все бессмысленно.
Если вы все еще настаиваете, то ошибка, которую вы называете не существует в этом коде.
Тем не менее, вы делать возникли проблемы с содержимым макроса, который читает и записывает одну переменную в выражении. Результат не определен:
#include <iostream>
#include <cmath>
#include <array>
#ifndef pow2C
double __tmpDouble__;
#define pow2C(a) ((__tmpDouble__=(a))*(__tmpDouble__))
#endifinline double calculateDistance(double *x, double *y, int NDims)
{
double d = 0;
for (int i = 0; i < NDims; i++)
// it is faster to calculate the difference once
d += pow2C(x[i] - y[i]);
return sqrt(d);
}
int main()
{
const size_t NUM_DIMS = 3;
std::array<double, NUM_DIMS> x{{5.0, 6.0, 7.0}};
std::array<double, NUM_DIMS> y{{1.2, 1.5, 9.0}};
std::cout << "Distance between x and y is: " << calculateDistance(&x[0], &y[0], NUM_DIMS) << '\n';
}
// g++-4.8 -std=c++11 -Wall -pedantic -pthread main.cpp && ./a.out
// main.cpp: In function 'double calculateDistance(double*, double*, int)':
// main.cpp:16:31: warning: operation on '__tmpDouble__' may be undefined [-Wsequence-point]
// d += pow2C(x[i] - y[i]);
// ^
// Distance between x and y is: 6.22013
Итак, действительно, мы вернулись к не делай этого.
Если вы все еще отчаянно пытаетесь избежать оценки x[i] - y[i]
дважды:
inline double calculateDistance(double* x, double* y, int NDims)
{
double d = 0;
for (int i = 0; i < NDims; i++) {
const double diff = x[i] - y[i];
d += diff * diff;
}
return sqrt(d);
}
Вы можете передать работу умножения другому inline
функция полезности, если хотите, но здесь нет необходимости в макросе.
Если вы настаиваете на написании макроса, используйте другое имя для переменной. Но твой макрос очень ужасен. Во-первых, это не потокобезопасно в отношении одновременных вызовов, поскольку потоки будут обращаться к одной и той же временной переменной. Также, самый макросы вообще очень злые (есть немного исключения хотя).
Тем не менее, то же самое (также с точки зрения производительности) может быть достигнуто гораздо проще (даже с поддержкой float
и другие типы с operator*
с шаблоном функции:
template <typename T>
T square(const T &v) {
return v * v;
}
Если вы хотите макрос, то #define pow2C square
(знак сарказма).
Это ужасный способ определения макроса! Вы никогда не должны вводить переменные как часть расчета. Вместо этого попробуйте это:
#define pow2C(a) ((a) * (a))
Однако макросы ужасны для такого рода вычислений, так как они могут быть неэффективными и вызывать нежелательные побочные эффекты. Например, если вы закодируете код, он расширится до:
(x[i] - y[i]) * (x[i] - y[i])
Где вы сделали вычитание дважды!
Вместо этого используйте шаблоны C ++:
template<class T>
T pow2C(const T &value)
{
return value * value;
}
Теперь вы только один раз будете делать вычитание!