如何在 C++ 中要求某些概念代码?
我如何要求并检查参数是否是 C++
中的某个概念?
例如,algorithm
标头中的 random_shuffle
函数要求其参数为 RandomAccessIterators:
template<typename _RandomAccessIterator>
inline void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
if (__first != __last)
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
}
我想我不能在我自己的代码中使用这些 __glibcxx_function_requires
等?它们如何工作?你在你的代码中检查类似的东西吗?
How do I require and check that an argument is a certain concept in C++
?
For example, the random_shuffle
function in the algorithm
header requires that its arguments are RandomAccessIterators:
template<typename _RandomAccessIterator>
inline void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
// concept requirements
__glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__glibcxx_requires_valid_range(__first, __last);
if (__first != __last)
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
}
I guess I can't use these __glibcxx_function_requires
etc. in my own code? How do they work? Do you check things like that in your code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Boost 有一个用于此目的的库。这可能比弄清楚如何使用 STL 实现者已经破解的版本更容易,并且有更详细的记录。
http://www.boost.org/doc/libs/ 1_40_0/libs/concept_check/concept_check.htm
Boost has a library for this. It's probably easier and more well documented than figuring out how to use the version your STL implementer has hacked together.
http://www.boost.org/doc/libs/1_40_0/libs/concept_check/concept_check.htm
除非您定义 _GLIBCXX_CONCEPT_CHECKS,否则这些宏将被定义。所以我尝试以两种方式编译:
没有概念检查:8行错误 - 哪个实例化,哪里,与运算符不匹配。一切都清楚了。
通过概念检查:相同的错误 + 50 行左右的“从此处实例化”乱码以“错误:请求从 'std::bi Direction_iterator_tag' 转换为非标量类型 'std::random_access_iterator_tag' 结尾”。哎哟!如果有 random_shuffle 算法的注释,我可以更快地弄清楚这一点。
一件事是您不一定需要这些检查。如果不满足要求,代码将无法编译。在我看来,一个简单的“无匹配运算符<”可能比 50 行胡言乱语(用晦涩的措辞)得出“功能需要低于可比的概念”的结论更清晰。
如果您想要进行这些检查(对于 random_shuffle 之类的事情),一种方法是将调用转发到另一个也接受正确迭代器标记的函数:
产生一条不错的消息:“没有匹配的函数可调用 'shuffle(std::_List_iterator& , std::_List_iterator&, std::bi Direction_iterator_tag)'"
你可以添加一个模板化重载,它在编译时断言(static_assert 随 C++0x 一起提供):
如果你想变得超级好, boost 的概念检查没有它们的位置。
These macros are defined away unless you define _GLIBCXX_CONCEPT_CHECKS. So I tried to compile this both ways:
Without concept checks: 8 lines of error - which instantiation, where, no match for operator. All is clear.
With concept checks: the same errors + 50 lines or so of "instantiated from here" gibberish ending with "error: conversion from 'std::bidirectional_iterator_tag' to non-scalar type 'std::random_access_iterator_tag' requested". Doh! I could have figured that out faster if there was a comment with the random_shuffle algorithm.
One thing is that you don't necessarily need these checks. The code will fail to compile if the requirements are not met. And it seems to me that a simple "no matching operator<" could be clearer than 50 lines of gibberish concluding (in obscure wording) that "function requires less-than-comparable concept".
If you want those checks (for things like random_shuffle), one way is to forward the call to another function that also accepts the right iterator tag:
produces a nice message: "no matching function for call to 'shuffle(std::_List_iterator&, std::_List_iterator&, std::bidirectional_iterator_tag)'"
And if you want to be über-nice, you can add a templated overload, that asserts at compile-time (static_assert comes with C++0x):
Not saying that boost's concept checks don't have their place.