C++ 无法为函数指针专门化函数
我正在使用VS2015更新3。我希望根据可调用对象的返回类型专门化一个函数。当可调用对象是函子时,一切都按预期工作。当可调用对象是函数或函数指针时,它无法专门化重载函数。我觉得我错过了一些明显的东西,但我已经一年多没有和SFINAE做过任何事情了 我遗漏了什么导致专业化失败C++ 无法为函数指针专门化函数,c++,c++11,c++14,c++17,C++,C++11,C++14,C++17,我正在使用VS2015更新3。我希望根据可调用对象的返回类型专门化一个函数。当可调用对象是函子时,一切都按预期工作。当可调用对象是函数或函数指针时,它无法专门化重载函数。我觉得我错过了一些明显的东西,但我已经一年多没有和SFINAE做过任何事情了 我遗漏了什么导致专业化失败 template <typename T> struct S { T mOp; template <typename = void> typename std::enable_
template <typename T>
struct S
{
T mOp;
template <typename = void>
typename std::enable_if<
std::is_same<
std::remove_cv_t<
std::remove_reference_t<
decltype(mOp())
>
>,
void
>::value
>::type func()
{
std::cout << "bool" << std::endl;
}
template <typename = void>
typename std::enable_if<
std::is_same<
std::remove_cv_t<
std::remove_reference_t<
decltype(mOp())
>
>,
bool
>::value
>::type func()
{
std::cout << "void" << std::endl;
}
};
template <typename T>
auto createS(T&& t)
{
return S<T>{ t };
}
void vfunc()
{
}
bool bfunc()
{
return true;
}
struct vfunctor
{
void operator()()
{
}
};
struct bfunctor
{
bool operator()()
{
return true;
}
};
void func()
{
createS(bfunc).func(); // Fails to specialize func()
createS(vfunc).func(); // Fails to specialize func()
createS(vfunctor{}).func();
createS(bfunctor{}).func();
}
模板
结构
{
T拖把;
模板
typename std::启用\u如果<
std::是一样的吗<
std::删除\u cv\t<
标准::删除参考<
decltype(mOp())
>
>,
无效的
>::价值
>::type func()
{
std::cout,
布尔
>::价值
>::type func()
{
std::cout这一切都不起作用,因为替换失败只是替换的直接上下文中的一个失败,而您正试图在不依赖于直接函数模板参数的上下文中进行替换
基于类模板参数,而不是本地函数模板参数,因此这些只是硬错误
最简单的方法是通过标记分派。将decltype(mOp())
包装到标记类型中,然后重载:
template <class T> struct tag { };
template <typename T>
struct S
{
T mOp;
void func() {
func_impl(tag<std::decay_t<decltype(mOp())>>{});
}
void func_impl(tag<bool> ) { std::cout << "bool\n"; }
void func_impl(tag<void> ) { std::cout << "void\n"; }
};
注意,这必须出现在各种func\u impl
重载的声明之后
template <class..., class U=T>
auto func()
-> decltype(func_impl(tag<std::decay_t<std::invoke_result_t<U>>>{}))
{
return func_impl(tag<std::decay_t<std::invoke_result_t<U>>>{});
}