简体   繁体   English

如何在C ++中定义pow2宏

[英]how to define a pow2 macro in C++

I want to have definition for pow2C as follows. 我想对pow2C进行如下定义。 But my compiler shows it (__tmpDouble__) is already defined. 但是我的编译器显示(__tmpDouble__)已经定义。 Please help me define it. 请帮我定义一下。

#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);
}

If you insist on writing a macro, use a different name for the variable. 如果您坚持要编写宏,请为变量使用其他名称。 But your macro is very terrible. 但是您的宏非常糟糕。 First, it isn't thread safe with regard to concurrent calls, since the threads would access the same temporary variable. 首先,就并发调用而言,它不是线程安全的,因为线程将访问同一临时变量。 Also, most macros are very evil in general (there are some exceptions though). 同样, 大多数宏通常都是非常邪恶的(尽管有一些例外)。

However, the same (also performance-wise) can be achieved much easier (even with support for float and other types with operator* with a function template: 但是,可以更轻松地实现相同的(在性能方面)(即使使用带有功能模板的operator*支持float和其他类型:

template <typename T>
T square(const T &v) {
    return v * v;
}

If you want a macro, then #define pow2C square ( sarcasm sign ). 如果要使用宏,请#define pow2C square讽刺符号 )。

That's a terrible way to define a macro! 这是定义宏的糟糕方法! You should never introduce variables as part of the calculation. 绝对不要在计算中引入变量。 Instead, try this: 相反,请尝试以下操作:

#define pow2C(a) ((a) * (a))

However, macros are terrible for this sort of computation as they can be inefficient and cause unwanted side effects. 但是,宏对于这种类型的计算非常糟糕,因为它们可能效率低下并导致不良的副作用。 For example, if you code it would expand to: 例如,如果您编写代码,它将扩展为:

 (x[i] - y[i]) * (x[i] - y[i])

Where you've done the subtraction twice! 在两次减法的地方!

Instead, use C++ templates: 而是使用C ++模板:

template<class T>
T pow2C(const T &value)
{
  return value * value;
}

Now you'll only do the subtraction calculation once! 现在,您只需要进行一次减法计算!

I want to calculate x[i]-y[i] only once and save it in a variable and use it. 我只想计算一次x [i] -y [i]并将其保存在变量中并使用它。

You already do only calculate it once. 您已经只计算了一次。 This is all pointless. 这一切都没有意义。

If you still insist, then the error you name does not exist in this code . 如果您仍然坚持,则您的错误名称在此代码中不存在

However, you do have a problem with the content of the macro, which both reads from and writes to a single variable within an expression. 但是,您确实对宏的内容有问题,该宏既可以读取表达式中的单个变量,也可以写入表达式中的单个变量。 The result is undefined: 结果是不确定的:

#include <iostream>
#include <cmath>
#include <array>

#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);
}

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

So, really, we're back to don't do this . 所以,实际上,我们不打算这样做


If you're still desperate to avoid evaluating x[i] - y[i] twice: 如果您仍然迫切希望避免两次评估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);
}

You can pass off the multiplication work to another inline utility function if you like, but there is no need for a macro here. 如果愿意,可以将乘法工作传递给另一个inline实用程序函数,但是这里不需要宏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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