【问题标题】:How does std::invoke(C++1z) work?std::invoke(C++1z) 是如何工作的?
【发布时间】:2015-11-01 13:38:47
【问题描述】:
namespace detail {
template <class F, class... Args>
inline auto INVOKE(F&& f, Args&&... args) ->
    decltype(std::forward<F>(f)(std::forward<Args>(args)...)) {
      return std::forward<F>(f)(std::forward<Args>(args)...);
}

template <class Base, class T, class Derived>
inline auto INVOKE(T Base::*pmd, Derived&& ref) ->
    decltype(std::forward<Derived>(ref).*pmd) {
      return std::forward<Derived>(ref).*pmd;
}

template <class PMD, class Pointer>
inline auto INVOKE(PMD pmd, Pointer&& ptr) ->
    decltype((*std::forward<Pointer>(ptr)).*pmd) {
      return (*std::forward<Pointer>(ptr)).*pmd;
}

template <class Base, class T, class Derived, class... Args>
inline auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args) ->
    decltype((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...)) {
      return (std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...);
}

template <class PMF, class Pointer, class... Args>
inline auto INVOKE(PMF pmf, Pointer&& ptr, Args&&... args) ->
    decltype(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...)) {
      return ((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...);
}
} // namespace detail

template< class F, class... ArgTypes>
decltype(auto) invoke(F&& f, ArgTypes&&... args) {
    return detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...);
}

我从这里看到了上面的实现:

http://en.cppreference.com/w/cpp/utility/functional/invoke

然后我想知道编译器如何匹配所需的确切版本。 SFINAE 是否适用于尾随返回类型?

【问题讨论】:

标签: c++ stl c++17


【解决方案1】:

SFINAE 是否适用于拖尾返回类型?

是的。尾随返回类型语法不会启用任何新功能,它只是使编写一些依赖于参数类型的返回类型的情况变得更容易。

template <class F, class... Args>
inline auto INVOKE(F&& f, Args&&... args) ->
   decltype(std::forward<F>(f)(std::forward<Args>(args)...) { ... }

也可以写成

template <class F, class... Args>
inline decltype(std::forward<F>(std::declval<F&>())(std::forward<Args>(std::declval<Args&>())...))
INVOKE(F&& f, Args&&... args) { ... }

例如,其他所有的都一样。这可以简化,但即使您简化它,返回类型不能使用与 return 表达式相同的语法这一事实使得很难理解正在发生的事情。因此有了新的语法。

SFINAE 唯一不起作用的情况是推导返回类型。他们也使用auto,但禁用SFINAE 的不是auto 关键字本身。

【讨论】:

  • 谢谢!顺便说一句,我刚刚注意到你引用的我尴尬的拼写:-(
  • @iDingDong 别担心,它实际上既可以作为“尾随”,也可以作为“尾随”。 :)
  • 我仍然想知道 SFINAE 是否需要任何 C++1z 核心语言功能才能处理这种情况?
  • @iDingDong 尾随返回类型语法是在 C++11 中添加的,从第一个版本开始,它就已经允许 SFINAE 工作。这就是我试图在回答中传达的内容。如果你能说出我的答案不清楚的地方,我会尝试编辑它。
猜你喜欢
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 2012-12-15
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多