c++ - std::invoke(C++1z) 如何工作?

标签 c++ stl c++17

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 是否适用于尾随返回类型?

最佳答案

does SFINAE work on tailing return type?

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

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 关键字本身。

关于c++ - std::invoke(C++1z) 如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33462729/

相关文章:

c++ - LNK2019 : Calling a function in WinMain

c++ - 使用 ifstream 和 QtCreator 从当前目录读取文件

c++ - 二进制搜索数学函数

c++ - STL 内部 : deque implementation

c++ - 使用较小的默认对齐方式重载 operator new

c++ - 在 C++17 中的每个实例化中生成一个新类型

C++ 指针引用、类和指针列表、奇怪的返回

c++ - GCC STL 是线程安全的吗?

c++ - std::vector 迭代器类型和允许的操作

c++ - 向数组中插入一个元素