通过SFINAE进行函数模板检测

问题描述 投票:0回答:0

我想编写一个函数,将 lambda 分派到外部库函数模板(如果该函数模板存在于库中)或直接执行 lambda。 我们可以使用如下所示的 SFINAE 来做到这一点:

#include <iostream>
#include <type_traits>

#ifdef _HAS_THE_FUNC
//This part comes from an external library that either provides the function (in an older version) or not (in a newer version).
namespace ext { namespace lib {
  template<int _N = 1, typename _F>
  void lib_fun(_F f) {
    std::cout << "LibFun<" << _N << ">" << std::endl;
    f();
  }
} }
#endif
// "Inject" a little helper into the library's namespace to detect the presence of the function
namespace ext { namespace lib {
  // Helper type to detect the presence of lib_fun
  template <typename _F>
  struct has_lib_fun {
    template <typename F>
    static auto test(int) -> decltype(lib_fun(std::declval<F>()), std::true_type{});

    template <typename>
    static auto test(...) -> std::false_type;

    using type = decltype(test<_F>(0));
    static constexpr bool value = type::value;
  };
  // Use SFINAE to conditionally select the return type of loop_fuse
  template <typename _F>
  auto safe_lib_fun(_F f, int) -> std::enable_if_t<has_lib_fun<_F>::value> {
    lib_fun(f);
  }
  template <typename _F>
  auto safe_lib_fun(_F f, double) {
    std::cout << "Workaround" << std::endl;
    return f();
  }
} }

int main() {
  ext::lib::safe_lib_fun([]() { std::cout << "Hello World" << std::endl; }, 0);
  return 0;
}

如果我构建并运行代码,我会得到预期的输出:

clang++ -std=c++17 main.cpp -o woFun && clang++ -std=c++17 main.cpp -D_HAS_THE_FUNC -o wFun

#./woFun
Workaround
Hello World
#./wFun
LibFun<1>
Hello World

如何将非类型模板参数

_N
添加到
safe_lib_fun

c++ template-meta-programming sfinae
© www.soinside.com 2019 - 2024. All rights reserved.