【问题标题】:Offset of a variable (inherited from the base template class) shadowed by a member with the same name被同名成员遮蔽的变量的偏移量(从基模板类继承)
【发布时间】:2018-03-24 18:40:11
【问题描述】:

我有一个使用继承实现的元组类(它来自 C++ 模板:完整指南,第 2 版,Vandevoorde,Josuttis,Gregor):

template<typename... _Value>
class Tuple {};

template<unsigned int HEIGHT, typename _Value>
class TupleElement {
public:
    TupleElement() = default;

    template<typename _OtherValue>
    TupleElement(_OtherValue && other): _value{std::forward<_OtherValue>(other)} {}

    _Value _value;
};

template<typename _Head, typename... _Tail>
class Tuple<_Head, _Tail...>: public TupleElement<sizeof...(_Tail), _Head>, public Tuple<_Tail...> {
    using HeadElement = TupleElement<sizeof...(_Tail), _Head>;
public:
    template<typename _HeadArgument, typename... _TailArgument>
    Tuple(_HeadArgument && head, _TailArgument &&... tail): HeadElement{std::forward<_HeadArgument>(head)}, Tuple<_Tail...>{std::forward<_TailArgument>(tail)...} {}

    _Head & getHead() {
        return static_cast<HeadElement *>(this)->get();
    }

    const _Head & getHead() const {
        return static_cast<const HeadElement *>(this)->get();
    }

    Tuple<_Tail...> & getTail() { return *this; }

    const Tuple<_Tail...> & getTail() const { return *this; }
};

template<>
class Tuple<> {};

我正在使用这个模板来创建新类型,就好像它们是具有按模板参数顺序排序的同质成员变量的结构一样。我需要每个继承的_value 成员的偏移量。我正在尝试使用offsetof 来实现它,但是将_value 与元组返回的类型一起传递:

using T = Tuple<int, float>;
offsetof(T, _value);

错误

1>***.cpp(22): error C2385: ambiguous access of '_value'
1>***.cpp(22): note: could be the '_value' in base 'TupleElement<1,int>'
1>***.cpp(22): note: or could be the '_value' in base 'TupleElement<0,float>'

【问题讨论】:

  • 没有这样的错误,因为没有类被实例化。请发帖minimal reproducible example
  • 把这个放在这里:有std::tuple
  • @PasserBy std::tuple 的实现不保留模板参数的顺序。
  • std::tuple 的实现不保留模板参数的顺序。 什么?你能说得更具体一点吗?
  • getHeight&lt;&gt;()的实现是...

标签: c++ templates inheritance tuples offset


【解决方案1】:

您的班级中有两个 _value,这就是错误的意思。 您可以像这样获得它们的偏移量:

int off1 = ((size_t)&reinterpret_cast<char const volatile&>((((T*)0)->::TupleElement<0, float>::_value)));
int off2 = ((size_t)&reinterpret_cast<char const volatile&>((((T*)0)->::TupleElement<1, int>::_value)));

【讨论】:

  • 绑定一个空引用是严格的UB。
  • 这就是 offsetof 在 VS2017 中的工作方式:)。如果您愿意,可以将其更改为指针。
  • @Alex - 如果特定编译器愿意定义行为,标准库可以使用正式 UB 的代码。 offsetof 成为 C 标准库的一部分的最初原因是您不能用适当的可移植代码编写它。
猜你喜欢
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多