gpt4 book ai didi

c++ - 通过运行时索引访问派生类中基类的成员

转载 作者:行者123 更新时间:2023-12-01 14:22:53 25 4
gpt4 key购买 nike

考虑以下代码

#include <array>
#include <iostream>

template <std::size_t> struct base {
std::size_t value;
};

struct derived: base<0>, base<1> {
using pointer_type = std::size_t derived::*;
static constexpr std::array<pointer_type, 2> members{{
&derived::base<0>::value,
&derived::base<1>::value
}};
constexpr std::size_t& operator[](std::size_t i) noexcept {
return this->*(members[i]);
}
constexpr const std::size_t& operator[](std::size_t i) const noexcept {
return this->*(members[i]);
}
};

int main(int, char**) {
derived x{42, 84};
std::cout << sizeof(base<0>) + sizeof(base<1>) << " " << sizeof(derived);
std::cout << std::endl;
std::cout << x[0] << " " << x[1];
std::cout << std::endl;
return 0;
}

它创建了一个带有数据成员的模板化结构base,以及一个继承自它的多个特化的结构derived。我想根据运行时提供的索引访问一个或另一个基类的 value。提供的代码似乎没有实现这一点,并且总是返回第一个 basevalue

我想实现它:

  • 不改变base的代码
  • 不改变 derivedbase 继承的方式
  • 不改变sizeof(derived)(技巧应该是constexpr/static)
  • 仅使用已定义的行为(例如没有未定义的行为reinterpret_cast)
  • 访问的复杂度应该是O(1)

换句话说,我不想改变的代码布局应该是:

#include <array>
#include <iostream>

template <std::size_t> struct base {
std::size_t value;
};

struct derived: base<0>, base<1> {
/* things can be added here */
constexpr std::size_t& operator[](std::size_t i) noexcept {
/* things can be added here */
}
constexpr const std::size_t& operator[](std::size_t i) const noexcept {
/* things can be added here */
}
};

int main(int, char**) {
derived x{42, 84};
std::cout << sizeof(base<0>) + sizeof(base<1>) << " " << sizeof(derived);
std::cout << std::endl;
std::cout << x[0] << " " << x[1];
std::cout << std::endl;
return 0;
}

问题:为什么当前的技巧不起作用,有没有办法让它起作用?

编辑:似乎是 GCC 错误。我举报了here .与 clang 的比较 here .

额外问题(对语言律师):它是 GCC 错误,还是根据 C++17 标准未定义的行为?

最佳答案

这看起来像一个 GCC 错误。你的原码produces Clang 的预期输出。

我找到的 GCC 解决方法是将 members 变成静态成员函数:

static constexpr array_type members() noexcept {
return {&base<0>::value, &base<1>::value};
}

constexpr std::size_t& operator[](std::size_t i) noexcept {
return this->*members()[i];
}

关于c++ - 通过运行时索引访问派生类中基类的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61675172/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com