是否有可能“固化”?没有 hack 的 `std::pair` 字段?

发布于 2024-09-16 22:14:38 字数 889 浏览 8 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相思碎 2024-09-23 22:14:38

这不是强制转换,但您可以执行以下操作:

std::pair<int, int>  x;
std::pair<const int, int> y( x );

这应该根据 §20.2.2/4 进行。

That's not a cast, but you can do the following:

std::pair<int, int>  x;
std::pair<const int, int> y( x );

This should work according to §20.2.2/4.

杀手六號 2024-09-23 22:14:38

这个怎么样:

template< typename T1, typename T2 >
struct ref_pair {
public:
    typedef const T1 first_type;
    typedef T2 second_type;

    ref_pair(first_type& f, second_type& s) : f_(f), s_(s) {}

    first_type& first() {return *f_;}
    second_type& second() {return *s_;}
private:
    first_type* f_;
    second_type* s_;
};

我知道,这是不同的,那些是功能。如果你真的很绝望,你可以将 firstsecond 转换为某种代理类型的对象,延迟评估 *f_*s_
然而,最终用户总有办法区分它们。


我认为以下内容是相当安全和可移植的,当然,使用reinterpret_cast没有任何保证:

std:::pair<const int,int>& rx = reinterpret_cast<std:::pair<const int,int>&>(x);

不过它感觉很脏。我现在要去洗手。

How about this:

template< typename T1, typename T2 >
struct ref_pair {
public:
    typedef const T1 first_type;
    typedef T2 second_type;

    ref_pair(first_type& f, second_type& s) : f_(f), s_(s) {}

    first_type& first() {return *f_;}
    second_type& second() {return *s_;}
private:
    first_type* f_;
    second_type* s_;
};

I know, it's different, those are functions. If you're really desperate, you can turn first and second 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:

std:::pair<const int,int>& rx = reinterpret_cast<std:::pair<const int,int>&>(x);

It feels dirty, though. I'm now going to wash my hands.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文