作为我之前的问题的后续,我试图检测需要显式专业化的模板函数的存在。
我当前的工作代码检测到非模板函数(感谢 DyP 的帮助),前提是它们至少采用一个参数,以便可以使用依赖名称查找:
// switch to 0 to test the other case
#define ENABLE_FOO_BAR 1
namespace foo {
#if ENABLE_FOO_BAR
int bar(int);
#endif
}
namespace feature_test {
namespace detail {
using namespace foo;
template<typename T> decltype(bar(std::declval<T>())) test(int);
template<typename> void test(...);
}
static constexpr bool has_foo_bar = std::is_same<decltype(detail::test<int>(0)), int>::value;
static_assert(has_foo_bar == ENABLE_FOO_BAR, "something went wrong");
}
(该ENABLE_FOO_BAR
宏仅用于测试目的,在我的真实代码中我没有这样的宏,否则我不会使用 SFINAE)
当编译器可以自动推导出模板参数时,这也可以与模板函数完美配合:
namespace foo {
#if ENABLE_FOO_BAR
template<typename T> int bar(T);
#endif
}
但是,当我尝试检测需要显式特化的模板函数时,会在存在static_assert
时启动:foo::bar()
namespace foo {
#if ENABLE_FOO_BAR
template<typename T, typename U> T bar(U);
#endif
}
//...
// error: static assertion failed: something went wrong
显然编译器无法推断出模板参数,bar()
因此检测失败。我试图通过明确地专门调用来修复它:
template<typename T> decltype(bar<int, T>(std::declval<T>())) test(int);
// explicit specialization ^^^^^^^^
这在foo::bar()
存在时工作正常(该功能被正确检测到)但现在所有地狱在foo::bar()
不存在时都会崩溃:
error: ‘bar’ was not declared in this scope
template<typename T> decltype(bar<int, T>(std::declval<T>())) test(int);
^
error: expected primary-expression before ‘int’
template<typename T> decltype(bar<int, T>(std::declval<T>())) test(int);
^
// lots of meaningless errors that derive from the first two
看来我的显式专业化尝试失败了,因为编译器不知道这bar
是一个模板。
我将为您省去我试图解决此问题的所有内容并直奔主题:如何检测template<typename T, typename U> T bar(U);
需要显式特化才能实例化的函数的存在?