Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有类型限制的完美转发_C++_C++11_Sfinae_Perfect Forwarding - Fatal编程技术网

C++ 具有类型限制的完美转发

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)); }

我希望对模板函数使用完美转发,以确保保留l值或r值,但同时我希望对可能的参数类型施加某些限制

例如,假设我只想将
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