C++ 具有类型限制的完美转发
我希望对模板函数使用完美转发,以确保保留l值或r值,但同时我希望对可能的参数类型施加某些限制 例如,假设我只想将C++ 具有类型限制的完美转发,c++,c++11,sfinae,perfect-forwarding,C++,C++11,Sfinae,Perfect Forwarding,我希望对模板函数使用完美转发,以确保保留l值或r值,但同时我希望对可能的参数类型施加某些限制 例如,假设我只想将T限制为一个可调用对象。 以下方法在我看来是正确的 template<typename T> typename std::enable_if<std::is_callable<T>>::value>::type myFun(T&& val) { foo(std::forward<T>(val)); }
T
限制为一个可调用对象。
以下方法在我看来是正确的
template<typename T>
typename std::enable_if<std::is_callable<T>>::value>::type myFun(T&& val)
{
foo(std::forward<T>(val));
}
模板
typename std::enable_if::value>::键入myFun(T&&val)
{
foo(std::forward(val));
}
但是,由于我还不能完全适应SFINAE的各种细微差别,我将非常感谢其他人的反馈
这是正确且惯用的方法吗?
std::is_callable
是C++17的一个特性
无论如何,由于函数myFun
不返回任何内容,因此将enable\u if
作为返回值有点奇怪。是的,当选择模板时,它将变成void
,但将其作为默认模板参数可能更清晰:
template<typename T, std::enable_if_t<std::is_callable_v<T()>, int> = 0>
void myFun(T&& val)
{
foo(std::forward<T>(val));
}
顺便说一下,std::is_callable是C++17的一个特性 无论如何,由于函数
myFun
不返回任何内容,因此将enable\u if
作为返回值有点奇怪。是的,当选择模板时,它将变成void
,但将其作为默认模板参数可能更清晰:
template<typename T, std::enable_if_t<std::is_callable_v<T()>, int> = 0>
void myFun(T&& val)
{
foo(std::forward<T>(val));
}
为什么不为
Allowed\u Type
专门化模板并禁用常规模板?这是一个更好的解决方案吗?(几乎)当您想要处理特定类型时,总是喜欢重载。@AndyG:同意,我这里只有两个重载,void myFun(const Allowed\u Type&)
和void myFun(Allowed\u Type&)
而且根本没有模板。@AndyG如果我想检查是否可调用,你会采取不同的做法吗?为什么不将模板专门化为允许的类型
并禁用常规模板?这是一个更好的解决方案吗?(几乎)当你想处理特定类型时,总是喜欢重载。@AndyG:同意,我这里只有两个重载,void myFun(const-Allowed\u-Type&)
和void myFun(Allowed\u-Type&&)
,而且根本没有模板。@AndyG如果我想检查是否可调用
,你会做得不同吗?除了MSVC坏了而且不理解这个问题之外,std::enable_if_t=0
比typename=std::enable_if_t
具有更好的重载解析属性。@Yakk:已更新,谢谢。在std::enable_if_t=0
和template
之间是否有一个偏好,除了在前者中有一个到bool的隐式转换,并且不需要检查::value
?::value
比{}
多5个字符之外。或者,std::is_callable_v
因为这是一个C++17特性,所以也同样短。如果有,为什么要使用enable_呢?如果类型与条件不匹配,则仅静态断言就足以失败。@Jean BernardJansen:删除第二个定义中的enable_if会使满足std::is_callable
的类型的函数调用不明确,但MSVC已损坏且不理解它的问题除外,std::enable_if_t=0
比typename=std::enable_if_t
具有更好的重载解析属性。@Yakk:已更新,谢谢。在std::enable_if_t=0
和template
之间是否有一个偏好,除了在前者中有一个到bool的隐式转换,并且不需要检查::value
?::value
比{}
多5个字符之外。或者,std::is_callable_v
因为这是一个C++17特性,所以也同样短。如果有,为什么要使用enable_呢?如果类型与条件不匹配,则仅静态断言就足以失败。@Jean BernardJansen:删除第二个定义中的enable_if会使满足std::is_callable