宏的模板专业化
我正在查看以下 ,在下面复制
#define FBGEMM_SPECIALIZED_REQUANTIZE(T) \
template <> \
FBGEMM_API void Requantize<T>( \
const int32_t* src, \
T* dst, \
const int64_t len, \
const RequantizationParams& params, \
int thread_id, \
int num_threads) { \
int64_t i_begin, i_end; \
fbgemmPartition1D(thread_id, num_threads, len, i_begin, i_end); \
for (int64_t i = i_begin; i < i_end; ++i) { \
dst[i] = Requantize<T>(src[i], params); \
} \
}
FBGEMM_SPECIALIZED_REQUANTIZE(uint16_t)
FBGEMM_SPECIALIZED_REQUANTIZE(int32_t)
#undef FBGEMM_SPECIALIZED_REQUANTIZE
它似乎是在使用宏来专门化功能。
我想知道这样做与没有宏和擅长于C ++的所有事物之间有什么区别?
I'm looking at the following function, reproduced below
#define FBGEMM_SPECIALIZED_REQUANTIZE(T) \
template <> \
FBGEMM_API void Requantize<T>( \
const int32_t* src, \
T* dst, \
const int64_t len, \
const RequantizationParams& params, \
int thread_id, \
int num_threads) { \
int64_t i_begin, i_end; \
fbgemmPartition1D(thread_id, num_threads, len, i_begin, i_end); \
for (int64_t i = i_begin; i < i_end; ++i) { \
dst[i] = Requantize<T>(src[i], params); \
} \
}
FBGEMM_SPECIALIZED_REQUANTIZE(uint16_t)
FBGEMM_SPECIALIZED_REQUANTIZE(int32_t)
#undef FBGEMM_SPECIALIZED_REQUANTIZE
It appears to be using a macro to specialize the functions.
I'm wondering what is the difference between doing that vs. no macros and just specializing everything like usual in C++?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如评论中所述,宏仅仅是关于更换文本(更准确地说:令牌)。宏无法做更多打字不能做的事情。而不是
作者可以在没有任何宏观的情况下拼出这两个专业。但是,这将导致代码重复。另一方面,可以避免这种情况,如Fabian Via:
然后
是
int32_t
的相同专业化。请注意,该功能的参数列表如何导致大量重复。通常避免使用宏,因为它们导致混淆,通常避免使用代码重复,因为它很难维护代码。它的权衡是要进行的。一次专门用于两种不同类型的替代方案是使用Sfinae,但这需要修改可能是不可取的主模板。或概念,但它们仅自C ++ 20以来才可用。
无论如何...
打字量。
As mentioned in comments, macros are merely about text replacement (more precisely: tokens). Macros cannot do something that more typing cannot do as well. Instead of
The author could have spelled out the two specializations without using any macro. However, this would lead to code duplication. This on the other hand can be avoided, as mentioned by fabian via:
and then
And same specialization for
int32_t
. Note how already the argument list of the function leads to lots of repetition. Macros are usually avoided because they lead to obfuscation, code duplication is usually avoided because it leads to hard to maintain code. Its a trade off to be made.The other alternative to specialize for two different types at once is to use sfinae, but that requires to modify the primary template which may not be desirable. Or concepts but they are only available since C++20.
Anyhow...
The amount of typing.
首先,我们应该从:
注意仅声明此模板。我找不到它的实现。请注意,它在标题文件中。
还有
uint8_t8_t8_t8_t
。
现在,作者计划使其仅适用于两种类型:
uint8_t
,uint16_t
和int32_t
。您可以看到这一点,因为宏
fbgemm_specialized_requantize
定义然后在这两种用法之后,它立即未定义。因此,质疑这在当前状态如何?
uint8_t
,uint16_t
和int32_t
),它将获取链接器错误:“对function tempalte .....”。uint8_t的指针
将使用一个实现,并且将使用其他实现来用于uint16_t
和int32_t
。这很好吗? IMO不是要获得编译错误而是链接错误是最好的。请注意,在开发新代码期间,直到不使用此代码(例如测试书面)构建可以通过,然后当您添加测试或使用新功能时,您就会获得链接器错误。
可以做得更好吗?是的!
但这取决于要求。解决此问题的一种方法是:
在标题文件中,已超载的老式功能:
然后在CPP文件中定义模板,然后在此功能中使用它:
现在不需要链接错误替换为编译错误,而不需要宏。
其他方法是将模板声明保留在标题文件中,并在CPP文件中定义它,为
uint8_t
提供专业化。因此,标题文件不变,在CPP中:
但是我不知道这是如何与其他过载的
recrece
进行交互的。First we should start from original template:
Note this template is only declared. I can't find implementation of it. Note it is in a header file.
There is also alternative specialization for
uint8_t
.Now author planed to make it work only for two types:
uint8_t
,uint16_t
andint32_t
.You can see this, since macro
FBGEMM_SPECIALIZED_REQUANTIZE
is defined then after those two usages it is immediately undefined.So question how this behaves in current state?
uint8_t
,uint16_t
andint32_t
), it will get linker error: "undefined reference to function tempalte .....".uint8_t
one implementation will be used and other implementation will be used foruint16_t
andint32_t
.Is this good? IMO not it is better to get compilation error instead linking error. Note that during development of new code, until this code is not in use (for example test written) build can pass, then when you add test or use new functionality then you got linker error.
Can this be done better? YES!
But it depends on requirements. One way to solve this is this way:
In header file have overloaded old fashioned functions:
Then in cpp file define template and just use it inside of this functions:
Now linker errors are replaced with compilation errors and macros are not needed.
Other way to do it is keep template declaration in header file and define it in cpp file providing specialization for
uint8_t
.So header file unchanged and in cpp:
but I do not know how this interacts with other overloads of
Requantize
.