我想编写一个函数,将 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
?