是否有可能“固化”?没有 hack 的 `std::pair` 字段?
在 C++ 中,编译以下代码:
std::pair <int, int> x;
static_cast <std::pair <const int, int>*> (&x);
给出错误:
error: invalid static_cast from type ‘std::pair<int, int>*’ to type ‘std::pair<const int, int>*’
我或多或少理解为什么会发生这种情况,因为原则上,对模板参数列表中的类型进行 cv 限定可以给出“不兼容”的结果。即使在这种情况下它不存在,编译器也无法知道它。
无论如何,有没有一种非黑客的方式来执行此转换?我对使用 reinterpret_cast
进行任何操作都持谨慎态度,就像我之前遇到过类型双关问题一样。另外,我不能使用临时变量,因为这是性能关键的代码。
编辑:
这就是我正在做的事情。我正在实现一个与 std::unordered_map 兼容的自定义容器接口。因此,其 value_type
需要是一个对
。对于某些优化,我需要在内部将值存储为pair
,而不使用const
。但是,如果我这样做,我就无法(没有reinterpret_cast
)在容器上实现迭代器,因为它们需要返回对值的引用,而我只有对这些非常量对的引用。
In C++, the compiling the following code:
std::pair <int, int> x;
static_cast <std::pair <const int, int>*> (&x);
gives an error:
error: invalid static_cast from type ‘std::pair<int, int>*’ to type ‘std::pair<const int, int>*’
I more or less understand why it happens, as cv-qualifying a type in a template parameter list can, in principle, give an "incompatible" result. And even if in this case it doesn't, compiler has no way to know it.
Anyway, is there a non-hackish way to perform this conversion? I'm wary of using reinterpret_cast
for anything as I've been by type-punning problems before. Also, I can't use temporaries since this is in performance-critical code.
EDIT:
Here is what I'm doing. I'm implementing a custom container interface-compatible with std::unordered_map
. Because of that, its value_type
needs to be a pair <const key_type, mapped_type>
. For some optimization, I need to internally store the values as pair <key_type, mapped_type>
, without const
. However, if I do that, I can't (without reinterpret_cast
) implement iterators over the container, as they need to return references to values and I have only references to these non-const pairs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不是强制转换,但您可以执行以下操作:
这应该根据 §20.2.2/4 进行。
That's not a cast, but you can do the following:
This should work according to §20.2.2/4.
这个怎么样:
我知道,这是不同的,那些是功能。如果你真的很绝望,你可以将
first
和second
转换为某种代理类型的对象,延迟评估*f_
和*s_
。然而,最终用户总有办法区分它们。
我认为以下内容是相当安全和可移植的,当然,使用
reinterpret_cast
没有任何保证:不过它感觉很脏。我现在要去洗手。
How about this:
I know, it's different, those are functions. If you're really desperate, you can turn
first
andsecond
into objects of some proxy type which delay-evaluate*f_
and*s_
.However, in the end there's always a way users can tell the difference.
I think the following would be reasonably safe and portable, although, of course, with
reinterpret_cast
nothing is guaranteed:It feels dirty, though. I'm now going to wash my hands.