模板中的奇怪#define?

时间:2010-09-15 13:24:30

标签: c++ templates macros coding-style c-preprocessor

我从库中获得了一小部分代码:

#define VMMLIB_ALIGN( var ) var

template< size_t M, typename T = float >
class vector
{

...

private:
// storage
VMMLIB_ALIGN( T array[ M ] );

};

你可以通过

来调用它
//(vector<float> myVector)
myVector.array;

没有括号或任何内容。

什么?


看完答案后,看来我应该做得更多了。 XCode的“跳转到定义”只给了我一个结果。搜索图书馆给了我另一个:

#ifndef VMMLIB_CUSTOM_CONFIG
#  ifndef NDEBUG
#    define VMMLIB_SAFE_ACCESSORS
#  endif
#  define VMMLIB_THROW_EXCEPTIONS
#  ifdef VMMLIB_DONT_FORCE_ALIGNMENT
#    define VMMLIB_ALIGN( var ) var
#  else
#    ifdef __GNUC__
#      define VMMLIB_ALIGN( var ) var __attribute__((aligned(16)))
#    elif defined WIN32
#      define VMMLIB_ALIGN( var ) __declspec (align (16)) var
#    else
#      error "Alignment macro undefined"
#    endif
#  endif
#endif

这提供了不同的设置,具体取决于它所构建的系统。

无论如何,谢谢。无法相信我对会员访问感到困惑!

4 个答案:

答案 0 :(得分:4)

最终,myVector.array引用类中的数组变量,变量不需要函数调用符号()

BTW / all-capital标识符只能用于预处理器宏(因为它们在这里)。在这种情况下,必须使用宏VMMLIB_ALIGN以便以后“增加”为array变量生成的代码“增强”(例如,在其前面加上static,extern,const,volatile或特定于编译器的东西)和/或添加一些相关的功能,例如在阵列上工作的get / set / search / clear / serialise函数。

一般情况下 - 当您不确定宏正在做什么时,您可以通过命令行开关运行编译器请求预处理器输出(在GNU g ++中,交换机为-E)来获得更多信息。 ...然后,您将能够看到C ++编译器正确处理的实际源代码。

编辑 - 你的评论几乎没有想法,但是在我自己的评论中包含的时间太长......

C ++类是私有的,直到提供了另一个访问说明符(但实际上公共接口通常首先放置,因此程序员仍然必须记住明确使用private)。结构体默认是公共的。因此,默认情况下,数据在最常见的编码风格中有效地暴露。并且,它不需要函数调用语义来访问它。 Objective-C可能会更好......你的评论意味着你对数据成员和函数使用函数调用表示法,默认情况下是隐藏的吗?有一个共同的符号真是太好了!在C ++中,困难的情况是你有类似的东西......

struct Point
{
    double x, y;
};

...

// client usage:
this_point.x += 3 - that_point.y;

...然后想改为......

struct Point
{
    double angle, distance;
};

...你需要一些非常花哨和冗长的手动编码而不是非常高效的代理对象x和y,以允许旧的客户端代码在动态计算x和y时保持不变,并更新角度和必要时的距离。统一的表示法很棒 - 允许实现变化而不更改客户端源代码(尽管客户端需要重新编译)。

答案 1 :(得分:3)

也许我过度使用了,但是如果你看一下#define宏,它只是将变量写入类中。

所以你有

class vector
{
...
  T array[ M ];
};

扩张后。所以它只是你班上的一个公共变量。

答案 2 :(得分:1)

array不是一种方法,它是一个大小为T的{​​{1}}类型的数组。

答案 3 :(得分:1)

首先,对于记录,模板与此无关。宏与您的类是模板的事实之间没有特殊的交互。

其次,按照宏的名称,我猜它是为了确保变量的对齐。

也就是说,要获得x类型的对齐实例X,您需要使用VMMLIB_ALIGN(X x);

在实践中,宏根本不做任何事情。它只是插入它的参数,因此上面的结果是代码X x;,而不是其他任何内容。

但是,根据硬件平台(因为对齐要求可能因平台而异)或者随着时间的推移,可能会对宏进行不同的定义(在早期使用虚拟占位符实现,然后将其替换为“真正的“后期实施”

但是,它似乎毫无意义,因为编译器已经确保所有变量的自然对齐。