C++ 模板函数实现不正确

标签 c++ function templates sfinae enable-if

我已经在此处(在单个头文件中)实现了此功能。

//header.h
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <stdint.h>
#include <type_traits>



   template < typename T,
           typename = std::enable_if<std::is_integral<T> >::type >
void f(T t) {
    printf("Integer function\n");
}

template void f(int i);

主要是下面...

#include "header.h"
int main(int argc, char** argv) {
    int p = 3;
    f(p);
}

它编译......没问题,但它没有显示 printf 的内容,我错过了什么?...... (我正在使用 eclipse 作为 IDE,这可能是个问题?)

还有一件事......这个实现有意义吗? (我想根据输入的类型编写不同的代码,无论它是否是无符号的)。

template < typename T,
           typename = std::enable_if<std::is_integral<T>::value>,
           typename = std::enable_if<std::is_unsigned<T>::value>
>
void f(T t) {
    printf("Unsigned f version.\n");
}

template < typename T,
           typename = std::enable_if<std::is_integral<T>::value>,
           typename = std::enable_if<std::is_signed<T>::value>
>
void f(T t) {
    printf("Signed f version.\n");
}

在这种情况下它无法编译...那么如何处理呢?

谢谢

更新...

我尝试了第一个代码中建议的修改,它给了我以下错误

..\header.h:19:58: error: type/value mismatch at argument 1 in template parameter list for 'template<bool <anonymous>, class _Tp> struct std::enable_if'
            typename = std::enable_if<std::is_integral<T> >::type >
                                                          ^
..\header.h:19:58: error:   expected a constant of type 'bool', got 'std::is_integral<_Tp>'
..\header.h:19:61: error: expected '>' before 'type'
            typename = std::enable_if<std::is_integral<T> >::type >
                                                             ^
..\main.cc: In function 'int main(int, char**)':

更新 2...

好吧,伙计们……我一直在努力弄清楚我不明白的是什么……所以我正在研究 type_traits 的代码(所以我的目标是了解我做错了什么。 ..)

我报告了 enable_if 的代码(来自 type_traits)。

template<bool, typename _Tp = void>
    struct enable_if //Lukkio decl. 1
    { };

  // Partial specialization for true.
  template<typename _Tp>
    struct enable_if<true, _Tp> //Lukkio decl. 2
    { typedef _Tp type; };

因为我想了解这样一行会发生什么:

template<
    typename T,
    typename = std::enable_if<std::is_integral<T>::value>
>
void function(T t) {
    printf("Is integral!\n");
}

所以假设 T 是固定的(比方说 int,它是整数)std::enable_if::value> 使用 decl。 1,但是假设 _Tp 是类型 void 所以实际上发生了什么,就减少而言(我现在用关键字 代替 T >int... 应该是这样的

template<
        typename int,
        typename = std::enable_if<std::is_integral<int>::value>
    >

template<
        typename int,
        typename = std::enable_if<1>
    >

所以我的问题是...第二个类型名称代表什么?

最佳答案

默认函数模板参数上的 SFINAE 并没有真正扩展。如果您想将单个重载限制为特定类型的类,则只能使用它。

对于非重叠的多重重载(比如你的有符号/无符号积分),你可以像这样在返回类型上使用 SFINAE:

#include <cstdio>
#include <type_traits>

template < typename T>
auto f(T t) 
    -> std::enable_if_t<std::is_unsigned<T>::value && std::is_integral<T>::value>
{
    printf("Unsigned f version.\n");
}

template < typename T>
auto f(T t) 
    -> std::enable_if_t<std::is_signed<T>::value && std::is_integral<T>::value>
{
    printf("Signed f version.\n");
}

int main()
{
    unsigned u = 1;
    signed s = 1;
    f(u);
    f(s);
}

Live Example

注意:enable_if_t<T>typename enable_if<T>::type 的类型别名在 C++14 中可用(您可以自己编写)

关于C++ 模板函数实现不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32740123/

相关文章:

c++ - getline 函数的奇怪循环行为

c++ - 如何静态链接到 TBB?

c++ - 如何创建容器模板(例如 std::map)?

php - 在mysql上查询数据后制作PHP页面

c++ - 通过引用传递(=返回)函数导出处的 vector

javascript - 将属性应用于 Angular Directive(指令)中的自定义嵌套元素

c++ - 使用 IGroupPolicyObject 更新 Windows 7 中的本地计算机策略

c++ - 使用 boost::shared_ptr 的多态分派(dispatch)

javascript - 使用按钮更改 javascript 变量

javascript - 在一个函数中传递一个参数,该参数在另一个函数中通过 "reference"传递