Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++;如何制作模板<;T>;f()返回-1表示整数T,nullptr表示指针类型_C++_Templates_C++11_Return Type_Sfinae - Fatal编程技术网

C++ C++;如何制作模板<;T>;f()返回-1表示整数T,nullptr表示指针类型

C++ C++;如何制作模板<;T>;f()返回-1表示整数T,nullptr表示指针类型,c++,templates,c++11,return-type,sfinae,C++,Templates,C++11,Return Type,Sfinae,我需要完成以下工作: template<typename T> f() { : return { -1 if T is of integral type, else nullptr } } 这是迄今为止我拥有的最佳解决方案: template<typename T> T test(typename enable_if<is_integral<T>::value, void*>::type = nullptr) { return -

我需要完成以下工作:

template<typename T>
f() {
    :
    return { -1 if T is of integral type, else nullptr }
}
这是迄今为止我拥有的最佳解决方案:

template<typename T>
T test(typename enable_if<is_integral<T>::value, void*>::type = nullptr)
{ return -1; }

template<typename T>
T test(typename enable_if<is_pointer<T>::value, void*>::type = nullptr)
{ return nullptr; }
模板
T测试(如果::type=nullptr,则类型名启用)
{return-1;}
模板
T测试(如果::type=nullptr,则类型名启用)
{return nullptr;}

但这是用大锤敲碎螺母吗

我唯一的反对意见是它解决了一个更广泛的问题范围,但我不确定它是否在没有额外修改std::decay的情况下是完整的

我习惯于抵制使代码复杂化的诱惑,这样它也可以解决手头问题范围的假想扩展


但在这种情况下,我看不到更简单的解决方案。

如果在返回类型上添加
enable\u if
,则会更加清晰:

template <typename T>
typename std::enable_if<is_integral<T>::value, T>::type
test() {
    return -1;
}

template <typename T>
typename std::enable_if<is_pointer<T>::value, T>::type
test() {
    return nullptr;
}
模板
typename std::enable_if::type
测试(){
返回-1;
}
模板
typename std::enable_if::type
测试(){
返回空ptr;
}

不要想太多。您可以简单地使用:

template<typename T>
T f() { return std::is_integral<T>::value ? T(-1) : T(0); }
模板
tf(){return std::is_integral::value?T(-1):T(0);}

如果
T
是指针类型,这甚至适用于
T(-1)
转换,因为该转换只能在运行时未定义,而不能在编译时定义,但在运行时从未实际执行。

通过请求,对于给定类型,可以简化为

template<typename T>
T f() { return -1; }

template<>
PyObject* f<PyObject*>() { return nullptr; }
模板
tf(){return-1;}
模板
PyObject*f(){return nullptr;}
模板
f2(std::true_type/*是整数*/){return-1;}
模板
f2(std::false_type/*是整数*/){return nullptr;}
模板
tf(){返回f2(std::is_integral{});}
如有疑问,请发送标签

您可以在详细信息命名空间中隐藏
f2

这消除了SFINAE的噪音


如果您希望SFINAE在错误类型上失败,您可以执行一些decltype和auto并链接到
f3
,以测试指针类型。更不用说垃圾邮件了。

我看你的解决方案没有问题。C++类型的特征经常类似于巨型大锤…如果只有三种可能的类型(<代码> int <代码> >代码> SsiZeZt,<代码> PyObjult*/Cuth>),为什么不为这些类型编写三个重载?@ Delnon,我尝试过重载,但是点击了“只有返回类型不同的函数不能重载”。错误。但是,您可以添加两个或三个显式专门化。@mAlters,您愿意将此作为答案吗?(或者其他人会这样做吗?这样可以并排看到各种解决方案路径)我认为第二种情况更适合使用原始的
is\u指针编写。这绝对更干净,谢谢。有几件事,也许把“你需要…”替换为“更好…”,因为原作是计算的,把T作为第二个参数来启用_if不是更有诗意吗?我不太确定<例如,代码>-1
可能与
int*
不正确对齐。@T.C.deref也不是未定义的。其结果是。更准确地说,该指针可能引用的是受保护的内存区域,在取消引用时会导致访问冲突。编辑为“可以”而不是“愿意”,希望避免这种讨论。在这里,它是否未定义并不重要,只是如果它未定义,它仍然不是问题。+1对于我想发布的解决方案:D@Pi
T(0)
T=void*
完全有效,其含义与
(T)0
相同。至于“<代码>:的结果,这是个坏主意,C++现在只把一个零值的整型文字作为空指针常数,而不是任何值为零的任意整数常量表达式,所以如果T是指针类型,则您的修改版本不再保证会导致空指针。
template<typename T>
T f() { return -1; }

template<>
PyObject* f<PyObject*>() { return nullptr; }
template<class T>
T f2(std::true_type /* is integral */){return -1;}
template<class T>
T f2(std::false_type /* is integral */){return nullptr;}
template<class T>
T f(){ return f2(std::is_integral<T>{}); }