【问题标题】:Type alias for function arguments in C++C++ 中函数参数的类型别名
【发布时间】:2017-10-26 23:16:05
【问题描述】:

我有这样的功能:

template <typename P1, typename... Ps> constexpr auto pipe(P1 &&proc1,
  Ps &&...procs) -> Cont<Cont<
    Proc<typename RevProc<P1>::ArgType,
      typename RevProc<typename Last<Ps...>::Type>::RetType>>> {
  using T = typename RevProc<P1>::ArgType;
  using U = typename RevProc<P1>::RetType;
  using V = typename RevProc<typename Last<Ps...>::Type>::RetType;
  return [&] (Cont<Proc<T, V>> &&pass) {
    pipe(move(procs)...)([&] (Proc<U, V> &&proc2) {
      pipe(move(proc1), move(proc2))(move(pass));
    });
  };
}

您可能会发现类型声明是重复的。有没有机会给这个函数一个签名,比如:

template <typename P1, typename... Ps> constexpr auto pipe(P1 &&proc1,
  Ps &&...procs) -> Cont<Cont<Proc<T, V>>>

并在某个适当的位置定义T 和V?

【问题讨论】:

  • 你能直接切换到 C++14 吗?
  • 其实我用的是C++14。我是新人,什么都不懂。
  • 啊,太好了,那就删除尾随的返回类型吧!如果你想返回那个实际的类型(而不是稍后转换),把类型转换放到 return 语句中。

标签: c++ c++11 refactoring using type-alias


【解决方案1】:

在 C++14 中,你可以只推导出类型:

template <typename P1, typename... Ps>
constexpr auto pipe(P1 &&proc1, Ps &&...procs) {
  using T = typename RevProc<P1>::ArgType;
  using U = typename RevProc<P1>::RetType;
  using V = typename RevProc<typename Last<Ps...>::Type>::RetType;
  return Cont<Cont<Proc<T, V>>>([&](Cont<Proc<T, V>> &&pass) {
    pipe(std::move(procs)...)([&](Proc<U, V> &&proc2) {
      pipe(std::move(proc1), std::move(proc2))(std::move(pass));
    });
  });
}

顺便说一句,您对std::move 的某些使用看起来不合法,因为pipe 很可能会使用调用者不希望从中移动的左值来调用。最好通过转发参考实际转发您所采取的:

  return Cont<Cont<Proc<T, V>>>([&](Cont<Proc<T, V>> &&pass) {
    pipe(std::forward<Ps>(procs)...)([&](Proc<U, V> &&proc2) {
      pipe(std::forward<P1>(proc1), std::move(proc2))(std::move(pass));
    });
  });

【讨论】:

  • 谢谢。很难想象我有一个如此强大的编译器,他花了我一整天的时间来解释整个 RevProc 的事情。
  • @Cowsay:是的,六年前是一段黑暗的时光 :-) 现在一切都变得更好了。
  • 就我个人而言,我会在传递给特征类的完美转发 arg 类型中添加一些 decay
猜你喜欢
  • 1970-01-01
  • 2015-09-15
  • 1970-01-01
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多