【问题标题】:What does this C++ template macro mean?这个 C++ 模板宏是什么意思?
【发布时间】:2015-11-03 20:05:39
【问题描述】:

有人可以帮我分解一下吗?我知道宏,并且我对模板相当熟悉,但我不知道作者用这个表达什么。预期用途是什么,为什么要这样写?我们在这里定义什么?如何以及为什么要使用它?

#define MY_CLASS(RET_TYPE, ... )\
    template<typename Derived>\
    __VA_ARGS__\
    RET_TYPE my_class_impl<Derived>

我也有类似的东西

MY_CLASS( )::my_class_impl( int arg_id )

我也看到了

template<typename Derived>
class my_class_impl

听同事说这是一个 CRTP(奇怪的是重复出现的模板模式)的案例,但他没有更具体的见解。

另外,我看到它随后使用如下:

MY_CLASS(some_type)::find_desired_val(int x) {
// some code
}

那么,在实际实现类my_class_impl时,宏是用来代替方法签名的?

【问题讨论】:

  • 什么是my_class_impl
  • typename Derived 使它看起来像一个 CRTP 在宏中捣碎。可以为RET_TYPE... 提供什么合理的参数,以及为什么在没有任何参数的情况下调用宏,我不知道。
  • @Quentin:想到了__decltype(dllexport)。但这是一个 MSVC++ 扩展。
  • @MSalters 哦。 IIRC MSVC 还具有调用缺少参数的宏的扩展。
  • 另外,我认为这是一个合理的问题。 OP 看到了代码并试图理解它。鉴于它充其量是令人费解的,我认为没有理由关闭它。

标签: c++ templates macros c++14 variadic-functions


【解决方案1】:

用于定义my_class_impl&lt;Derived&gt;的成员函数。

MY_CLASS(void)::member(Bar b) {}

扩展为:

template <typename Derived>
void my_class_impl<Derived>::member(Bar b) {}

可变参数宏参数可用于各种(标准或非标准)属性,例如__declspec(...)[[...]] 等。例如:

MY_CLASS(void, __declspec(dllexport))::foo();

扩展为:

template <typename Derived>
__declspec(dllexport) void my_class_impl<Derived>::foo() {}

MY_CLASS()::my_class_impl(int arg_id),由于允许缺少宏参数的编译器扩展(存在于 MSVC,以及 Clang 和 GCC,我弄错了),扩展为构造函数:

template <typename Derived>
/* nothing */ my_class_impl<Derived>::my_class_impl(int arg_id) {}

这也是一个相当丑陋的宏。它不仅难以理解,而且隐藏了非常普通的东西,如果您尝试返回包含逗号的类型 (std::map&lt;int, int&gt;),它就会中断。

【讨论】:

  • 非常感谢,这很有道理。更详细一点,如果 VA_ARGS 实际上代表几个额外的参数怎么办?那么方法签名将如何扩展呢?你能提供具体的例子吗?
  • @BaronYugovich 添加了示例。
【解决方案2】:

RET_TYPE 暗示这是一个函数,MY_CLASS 特别暗示了成员函数。这些也可以声明为static

不太常见的是 [[noreturn]][[deprecated]],它们是 C++14 属性。

&lt;Derived&gt; 部分与此无关,类模板可以像类一样具有成员函数。

【讨论】:

  • 嗯,是的,这是 C++14。
猜你喜欢
  • 2013-05-16
  • 1970-01-01
  • 2015-01-09
  • 2014-04-25
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 2011-11-13
相关资源
最近更新 更多