有人可以帮我解决这个问题吗?我知道宏,我对模板非常熟悉,但我不知道作者用这个表达了什么。什么是预期用途,为什么这样写?我们在这里定义的是什么?如何以及为什么使用它?
#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
的方法签名?
答案 0 :(得分:10)
它用于定义my_class_impl<Derived>
的成员函数。
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<int, int>
)的类型,则会中断。
答案 1 :(得分:2)
RET_TYPE
暗示这是一个函数,MY_CLASS
特别提示成员函数。这些也可以声明static
。
不太常见的是[[noreturn]]
或[[deprecated]]
,它们是C ++ 14属性。
<Derived>
部分与此无关,类模板可以像类一样具有成员函数。