【问题标题】:How to perfectly forward a struct member?如何完美转发结构成员?
【发布时间】:2016-06-25 00:36:57
【问题描述】:

我正在尝试进行一些通用编程,其中我获取某个结构的实例(已以某种方式注册)并对其成员的某些子集执行特殊操作。

我有一个看起来像这样的特质:

template <typename S>
struct visitable<S, std::enable_if_t<is_visitable<S>::value>> {
  template <typename V, typename T>
  static void apply_visitor(V && v, T && t) {
    v(t.*(get_registered_member_ptr<S>::value));
  }
}

template <typename V, typename S>
void apply_visitor(V && v, S && s) {
  visitable<std::remove_cv_t<std::remove_reference_t<S>>>::apply_visitor(std::forward<V>(v), std::forward<S>(s));
}

这是一个简化,实际上会有几个成员指针,访问者会被应用多次。但它触及了问题的核心。

在此代码中,T 将与 S 具有相同的类型,但带有一些 CV / 引用限定符,我正在使用这些限定符,因此我不必手动输入所有重载。我想用与用户传递的表达式相同的值类型来调用访问者。

但是当我想将指针应用到成员时,我遇到了一个问题,因为当我将 std::forward 传递给访问者时,我无法再使用它来获得正确的限定符。

是否有 std::forward 的精美版本可以做到这一点,例如,将第一个模板参数的 CV 和引用限定符应用于第二个参数并给我结果?还是我应该只补一张?或者有没有更好的成语。

【问题讨论】:

  • 我不希望编写和设计良好的 C++ 代码使用remove_cv_t 到如此极端的程度。这看起来像是某种设计问题。
  • @SamVarshavchik:这只是因为,当类型被注册时,它没有 CV 或 ref 限定符,但是当它通过完美转发传递时,它确实如此。如果我没有remove_cv_t 等,那么要么找不到模板专业化,要么您需要额外注册 5 或 6 次。

标签: c++ templates c++11 perfect-forwarding pointer-to-member


【解决方案1】:
std::forward<V>(v)(std::forward<T>(t).*(get_registered_member_ptr<S>::value))

应该做的伎俩。

【讨论】:

  • 啊...我明白了,所以.* 运算符将使用右值引用做正确的事情。我没有意识到这一点。谢谢。
  • @chris 我知道. 会做正确的事。我没有仔细检查.* 会,但我认为标准作家的能力。
猜你喜欢
  • 2022-11-20
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多