使用 static_assert 检查传递给宏的类型
不幸的是,我的库的原始版本留下了几个宏,这些宏使用了一些非常疯狂的 C。特别是,我有一系列宏,它们期望将某些类型传递给它们。 是否可以按照以下方式做一些事情:
static_assert(decltype(retval) == bool);
以及如何做?有什么聪明的替代方案吗?
是的,我知道宏很糟糕。我知道 C++ 不是 C 等。
Update0
I unfortunately have several macros left over from the original version of my library that employed some pretty crazy C. In particular, I have a series of macros that expect certain types to be passed to them. Is it possible to do something along the lines of:
static_assert(decltype(retval) == bool);
And how? Are there any clever alternatives?
Yes I'm aware macros are bad. I'm aware C++ is not C, etc.
Update0
Here is some related code, and the source file. Suggestions are welcome. The original question remains the same.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我发现这是最干净的,使用 @UncleBens 建议:
I found this to be the cleanest, using @UncleBens suggestion:
如果您确实关心
const
和易失性
限定符,并且希望确保类型也与您要比较的类型完全匹配,就像@Matt Joiner所说:我你不关心
const
,但是,如果想要简单地确保类型是某种类型而不考虑const
,请改为执行以下操作。请注意,这里需要std::remove_const<>::type
:volatile
也是如此。如果您也不关心类型的易失性
部分,则可以使用std::remove_volatile<>::type
忽略它:如果您不这样做不关心
const
或volatile
,您可以使用std::remove_cv<>::type
删除它们:另请注意,截至C++17 你可以这样做:
std::remove_cv_t
代替std::remove_cv::type
,并且:用std::is_same_v
代替std::is_same::value
。参考文献:
std::remove_cv<>
、std::remove_const
、std::remove_volatile<>< /code>
相关:
static_assert
技巧的另一个答案] 如何制作跨度If you DO care about the
const
andvolatile
qualifiers, and want to ensure theconst
andvolatile
parts of the types also exactly match the type you are comparing against, do like @Matt Joiner says:I you do NOT care about
const
, however, and want to simply ensure the type is a certain type without regard forconst
, do the following instead. Note thatstd::remove_const<>::type
is required here:The same goes for
volatile
. In case you don't care about thevolatile
part of the type either, you can ignore it withstd::remove_volatile<>::type
:If you don't care about
const
ORvolatile
, you can remove them both withstd::remove_cv<>::type
:Note also that as of C++17 you can do:
std::remove_cv_t<decltype(my_variable)>
in place ofstd::remove_cv<decltype(my_variable)>::type
, and:std::is_same_v<some_type, another_type>
in place ofstd::is_same<some_type, another_type>::value
.References:
std::remove_cv<>
,std::remove_const<>
,std::remove_volatile<>
Related:
static_assert
tricks] How to make span of spans免责声明:这是一个糟糕的答案,肯定有更好的解决方案。只是一个例子:)
它肯定已经实现了,但是自己实现是微不足道的;
像这样使用:
替代(GMan 建议):
Disclaimer: This is a bad answer, there are definitely far better solutions. Just an example :)
It is bound to be already implemented, but it's trivial to implement yourself;
To be used like this:
Alternative (suggested by GMan):
To be used like
看来您需要
decltype
因为您有一个表达式,但想要验证类型。现在已经有足够的方法可以做到这一点(C++03)。例如,要检查 boolIt appears you need
decltype
because you've got an expression, but want to verify a type. There are already enough ways to do that now (C++03). For instance, to check a bool大多数宏都可以替换为内联函数和/或模板。作为一个恰当的例子,过于聪明的参数大小检查 Posix isnan 宏是 C++0x 中的一个模板。哦,例子不好,但你明白了。
该规则的主要例外是本质上实现更高级别语言功能的宏。例如,更智能的异常处理、协方差或参数化声明集。
在某些情况下,无法合理表示为内联函数或模板的宏可以用更智能的预处理(即代码生成)来替换。然后你在某个地方有一个脚本可以生成必要的代码。例如,可以使用宏和模板在纯 C++ 中创建选项类,但它很麻烦,并且作为一种更容易理解并且可能更易于维护的替代方案,可以使用生成必需类的脚本,但需要额外的成本构建步骤并处理多种语言。
干杯&呵呵,,
Most macros can be replaced with
inline
functions and/or templates. As a case in point, the overly clever argument-size-checking Posixisnan
macro is a template in C++0x. Oh,bad example, but you get the idea.The main exceptions to that rule are macros that essentially implement higher level language features. For example, smarter exception handling, or covariance, or a parameterized set of declarations.
In some cases the macros that can't be reasonable expressed as
inline
functions or templates, can be replaced with a smarter kind of preprocessing, namely code generation. Then you have a script somewhere that generates the necessary code. For example, it's possible to do options classes in pure C++ with macros and templates, but it's hairy, and as an easier-to-grok and perhaps more maintainable alternative one might use a script that generates the requisite classes, at the cost of extra build steps and dealing with multiple languages.Cheers & hth.,