如何限制函数模板的类型范围

singshell 2016-02-24 11:12:52
加精
如题,
我想限制 template < class T > 中T 的范围只能是 int 和 long 这两种类型,该如何写?
...全文
2837 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
singshell 2016-03-02
  • 打赏
  • 举报
回复
引用 30 楼 xuzzzhen123 的回复:
[quote=引用 29 楼 singshell 的回复:] [quote=引用 28 楼 xuzzzhen123 的回复:] 这个方法可以的。
我这里报错如下: error: expected nested-name-specifier before 'int_traits' 还是重载吧。[/quote] 第12行不小心写错了,正确的写法是: typedef typename integer_traits <T>::int_type int_t; 请不要用重载,做良心程序员,永远写自己能写的最优秀代码。加油![/quote] 没看明白 对于下面的两个函数您就说说这怎么用吧: int test ( int var) { return var; } long test ( long var ) { return var; }
天外怪魔 2016-03-02
  • 打赏
  • 举报
回复
引用 29 楼 singshell 的回复:
[quote=引用 28 楼 xuzzzhen123 的回复:] 这个方法可以的。
我这里报错如下: error: expected nested-name-specifier before 'int_traits' 还是重载吧。[/quote] 第12行不小心写错了,正确的写法是: typedef typename integer_traits <T>::int_type int_t; 请不要用重载,做良心程序员,永远写自己能写的最优秀代码。加油!
天外怪魔 2016-03-02
  • 打赏
  • 举报
回复
引用 35 楼 iyomumx 的回复:
就算没有C++11支持,思路也是一样的: 1.构造一个只有int和long特化的模板类 2.利用特化的模板类成员做(函数参数/模板参数/函数返回)类型,使得除int/long以外的类型匹配失败 比如
template <typename T> struct Checker;
template <> struct Checker<int> { typedef int Type; };
template <> struct Checker<long> { typedef long Type; };

template <typename T>
typename Checker<T>::Type
test1(T var)
{
    return var;
}

int main()
{
    int i = 1;
    long l = 2L;
    double d = 3.0;
    test1(i);
    test1(l);
    //test1(d);  //该语句会编译失败
    return 0;
}
这也是个办法。更接近函数的限定。
iyomumx 2016-03-02
  • 打赏
  • 举报
回复
就算没有C++11支持,思路也是一样的: 1.构造一个只有int和long特化的模板类 2.利用特化的模板类成员做(函数参数/模板参数/函数返回)类型,使得除int/long以外的类型匹配失败 比如
template <typename T> struct Checker;
template <> struct Checker<int> { typedef int Type; };
template <> struct Checker<long> { typedef long Type; };

template <typename T>
typename Checker<T>::Type
test1(T var)
{
    return var;
}

int main()
{
    int i = 1;
    long l = 2L;
    double d = 3.0;
    test1(i);
    test1(l);
    //test1(d);  //该语句会编译失败
    return 0;
}
天外怪魔 2016-03-02
  • 打赏
  • 举报
回复
引用 33 楼 singshell 的回复:
[quote=引用 32 楼 xuzzzhen123 的回复:]
第4行有什么作用,是不是可有可无,我把它删了也没有error。[/quote] 定义常量类型。 老板您要是没有问题了麻烦结贴。 我需要在C++版提高等级以后好在这里招人,谢谢。 ========================================== By 伟大的领袖、伟大的导师、伟大的舵手、天才程序员:xuzzzhen123
singshell 2016-03-02
  • 打赏
  • 举报
回复
引用 32 楼 xuzzzhen123 的回复:
第4行有什么作用,是不是可有可无,我把它删了也没有error。
天外怪魔 2016-03-02
  • 打赏
  • 举报
回复
引用 31 楼 singshell 的回复:
[quote=引用 30 楼 xuzzzhen123 的回复:] [quote=引用 29 楼 singshell 的回复:] [quote=引用 28 楼 xuzzzhen123 的回复:] 这个方法可以的。
我这里报错如下: error: expected nested-name-specifier before 'int_traits' 还是重载吧。[/quote] 第12行不小心写错了,正确的写法是: typedef typename integer_traits <T>::int_type int_t; 请不要用重载,做良心程序员,永远写自己能写的最优秀代码。加油![/quote] 没看明白 对于下面的两个函数您就说说这怎么用吧: int test ( int var) { return var; } long test ( long var ) { return var; } [/quote]
template <typename T>struct integer_func
{
    typedef typename integer_traits <T>::int_type  int_t;
    typedef const int_t cint_t;

    int_t Test(int_t var) { return var;};
};


int _tmain(int argc, _TCHAR* argv[])
{
    integer_func<int> int_func;
    integer_func<long> long_func;
    // 下面一个语句不能编译,因为没有针对 char ,对   integer_traits 模板类型 做偏特化
    // integer_func<char> char_func;

    int i = int_func.Test(8);
    long j = long_func.Test(9);
    

    cout << i << endl;
    cout << j << endl;
}
singshell 2016-03-01
  • 打赏
  • 举报
回复
引用 28 楼 xuzzzhen123 的回复:
这个方法可以的。
我这里报错如下: error: expected nested-name-specifier before 'int_traits' 还是重载吧。
天外怪魔 2016-03-01
  • 打赏
  • 举报
回复
引用 7 楼 lm_whales 的回复:
#include <iostream>
using namespace std;

template < typename T >struct integer_traits;
template < >struct integer_traits<int>{
typedef int int_type;
};
template < >struct integer_traits<long>{
typedef long int_type;
};
template <typename T,int N >struct integer_arr{
    typedef typename int_traits <T>::int_type  int_t;
    typedef const int_t cint_t;

    int_t a[N];
    int_t& operator [](int n){return a[n];};
    cint_t& operator [](int n)const {return a[n];};
    size_t size()const {return N;};
};

int main()
{
    typedef integer_arr<int,8> int_arr;///int 可以
    typedef integer_arr<long,8> long_arr; ///long 可以

    int_arr ia;
    long_arr la;
    for(int i=0;i<8;i++){


    la[i]=10+i;
    ia[i]=20+i*i;
    }
    for(int i=0;i<8;i++){
        cout<<"ia["<<i<<"]="<<ia[i]<<endl;
        cout<<"la["<<i<<"]="<<la[i]<<endl;
    }
    /// 下面两个语句不能编译,因为没有针对 char ,对   integer_traits 模板类型 做偏特化
    ///typedef integer_arr<char,8> char_arr; 
    ///char_arr ca;

    return 0;
}
这个方法可以的。
伊顺鸣 2016-03-01
  • 打赏
  • 举报
回复
好帖啊!难得一见的好贴。。。
fefe82 2016-02-29
  • 打赏
  • 举报
回复
引用 19 楼 singshell 的回复:
[quote=引用 18 楼 fefe82 的回复:] [quote=引用 16 楼 singshell 的回复:] [quote=引用 15 楼 akirya 的回复:] [quote=引用 14 楼 singshell 的回复:] [quote=引用 13 楼 fefe82 的回复:] [quote=引用 12 楼 singshell 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 4 楼 sdghchj 的回复:] 在函数体里T的位置外全用如下式替换: typename std::enable_if<std::is_integral<T>::value, T>::type
template<class T>
typename std::enable_if < std::is_same<int, T>::value || std::is_same<long, T>::value , void >::type
func( T v )
{
};
[/quote] 编译时显示错误,如下: error: 'enable_if' in namespace 'std' does not name a type error: expected unqualified-id before '<' token[/quote] 啥版本的啥编译器?[/quote] codeblocks 里的 GNU GCC 编译器[/quote] 加上 #include <type_traits>[/quote] 增加了一个新错误,如下: d:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\c++0x_warning.h|32|error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.|[/quote] gcc 如果可能,能找到多高的版本就用多高的版本。 现在 gcc 4.9 和 5.2 都已经有了(mingw 不清楚)。 另外你需要按照编译提示加上 -std=c++11。[/quote] 也就是说这种方法 只针对高版本的编译器。适用性不广。[/quote] 低版本编译器,可以参考 boost 。
  • 打赏
  • 举报
回复
引用 24 楼 singshell 的回复:
[quote=引用 23 楼 akirya 的回复:] codeblocks 16.01 带的gcc 4.9.2直接编译通过
如果是上述裸函数的话确实可以通过,但是套到我已经写好的函数里就不行了,大神帮忙看看,我的函数代码如下: double new_random_function (double head, double tail) { double a, b, c; long random_num, random_max; long i; random_num = rand(); random_max = RAND_MAX; //printf("%ld\t%ld\n", random_num, random_max); a = (double)random_num; b = (double)random_max; c = a/b; // double random number //printf("%lf\t%lf\t%lf\n", a, b, c); return head + (tail - head) * c; }[/quote] 那就是用错了呗,这个代码也没看到哪里用了
singshell 2016-02-29
  • 打赏
  • 举报
回复
引用 23 楼 akirya 的回复:
codeblocks 16.01 带的gcc 4.9.2直接编译通过
如果是上述裸函数的话确实可以通过,但是套到我已经写好的函数里就不行了,大神帮忙看看,我的函数代码如下: double new_random_function (double head, double tail) { double a, b, c; long random_num, random_max; long i; random_num = rand(); random_max = RAND_MAX; //printf("%ld\t%ld\n", random_num, random_max); a = (double)random_num; b = (double)random_max; c = a/b; // double random number //printf("%lf\t%lf\t%lf\n", a, b, c); return head + (tail - head) * c; }
  • 打赏
  • 举报
回复
引用 19 楼 singshell 的回复:
也就是说这种方法 只针对高版本的编译器。适用性不广。
只是库是C++11的库而已 把库代码copy出来,完全可以用的

struct false_type
{
	const static bool value = false;
};

struct true_type
{
	const static bool value = true;
};

  template<typename, typename>
    struct is_same
    : public false_type { };

  template<typename _Tp>
    struct is_same<_Tp, _Tp>
    : public true_type { };
	
	  template<bool, typename _Tp = void>
    struct enable_if 
    { };

  // Partial specialization for true.
  template<typename _Tp>
    struct enable_if<true, _Tp>
    { typedef _Tp type; };
	
	
template<class T>
typename enable_if < is_same<int, T>::value || is_same<long, T>::value , void >::type
func( T v )
{
};
singshell 2016-02-25
  • 打赏
  • 举报
回复
引用 18 楼 fefe82 的回复:
[quote=引用 16 楼 singshell 的回复:] [quote=引用 15 楼 akirya 的回复:] [quote=引用 14 楼 singshell 的回复:] [quote=引用 13 楼 fefe82 的回复:] [quote=引用 12 楼 singshell 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 4 楼 sdghchj 的回复:] 在函数体里T的位置外全用如下式替换: typename std::enable_if<std::is_integral<T>::value, T>::type
template<class T>
typename std::enable_if < std::is_same<int, T>::value || std::is_same<long, T>::value , void >::type
func( T v )
{
};
[/quote] 编译时显示错误,如下: error: 'enable_if' in namespace 'std' does not name a type error: expected unqualified-id before '<' token[/quote] 啥版本的啥编译器?[/quote] codeblocks 里的 GNU GCC 编译器[/quote] 加上 #include <type_traits>[/quote] 增加了一个新错误,如下: d:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\c++0x_warning.h|32|error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.|[/quote] gcc 如果可能,能找到多高的版本就用多高的版本。 现在 gcc 4.9 和 5.2 都已经有了(mingw 不清楚)。 另外你需要按照编译提示加上 -std=c++11。[/quote] 也就是说这种方法 只针对高版本的编译器。适用性不广。
fefe82 2016-02-25
  • 打赏
  • 举报
回复
引用 16 楼 singshell 的回复:
[quote=引用 15 楼 akirya 的回复:] [quote=引用 14 楼 singshell 的回复:] [quote=引用 13 楼 fefe82 的回复:] [quote=引用 12 楼 singshell 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 4 楼 sdghchj 的回复:] 在函数体里T的位置外全用如下式替换: typename std::enable_if<std::is_integral<T>::value, T>::type
template<class T>
typename std::enable_if < std::is_same<int, T>::value || std::is_same<long, T>::value , void >::type
func( T v )
{
};
[/quote] 编译时显示错误,如下: error: 'enable_if' in namespace 'std' does not name a type error: expected unqualified-id before '<' token[/quote] 啥版本的啥编译器?[/quote] codeblocks 里的 GNU GCC 编译器[/quote] 加上 #include <type_traits>[/quote] 增加了一个新错误,如下: d:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\c++0x_warning.h|32|error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.|[/quote] gcc 如果可能,能找到多高的版本就用多高的版本。 现在 gcc 4.9 和 5.2 都已经有了(mingw 不清楚)。 另外你需要按照编译提示加上 -std=c++11。
singshell 2016-02-25
  • 打赏
  • 举报
回复
引用 4 楼 sdghchj 的回复:
在函数体里T的位置外全用如下式替换: typename std::enable_if<std::is_integral<T>::value, T>::type
这个并没有制定 int 和 long
singshell 2016-02-25
  • 打赏
  • 举报
回复
引用 15 楼 akirya 的回复:
[quote=引用 14 楼 singshell 的回复:] [quote=引用 13 楼 fefe82 的回复:] [quote=引用 12 楼 singshell 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 4 楼 sdghchj 的回复:] 在函数体里T的位置外全用如下式替换: typename std::enable_if<std::is_integral<T>::value, T>::type
template<class T>
typename std::enable_if < std::is_same<int, T>::value || std::is_same<long, T>::value , void >::type
func( T v )
{
};
[/quote] 编译时显示错误,如下: error: 'enable_if' in namespace 'std' does not name a type error: expected unqualified-id before '<' token[/quote] 啥版本的啥编译器?[/quote] codeblocks 里的 GNU GCC 编译器[/quote] 加上 #include <type_traits>[/quote] 增加了一个新错误,如下: d:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\c++0x_warning.h|32|error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.|
  • 打赏
  • 举报
回复
引用 14 楼 singshell 的回复:
[quote=引用 13 楼 fefe82 的回复:] [quote=引用 12 楼 singshell 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 4 楼 sdghchj 的回复:] 在函数体里T的位置外全用如下式替换: typename std::enable_if<std::is_integral<T>::value, T>::type
template<class T>
typename std::enable_if < std::is_same<int, T>::value || std::is_same<long, T>::value , void >::type
func( T v )
{
};
[/quote] 编译时显示错误,如下: error: 'enable_if' in namespace 'std' does not name a type error: expected unqualified-id before '<' token[/quote] 啥版本的啥编译器?[/quote] codeblocks 里的 GNU GCC 编译器[/quote] 加上 #include <type_traits>
singshell 2016-02-25
  • 打赏
  • 举报
回复
引用 13 楼 fefe82 的回复:
[quote=引用 12 楼 singshell 的回复:] [quote=引用 9 楼 akirya 的回复:] [quote=引用 4 楼 sdghchj 的回复:] 在函数体里T的位置外全用如下式替换: typename std::enable_if<std::is_integral<T>::value, T>::type
template<class T>
typename std::enable_if < std::is_same<int, T>::value || std::is_same<long, T>::value , void >::type
func( T v )
{
};
[/quote] 编译时显示错误,如下: error: 'enable_if' in namespace 'std' does not name a type error: expected unqualified-id before '<' token[/quote] 啥版本的啥编译器?[/quote] codeblocks 里的 GNU GCC 编译器
加载更多回复(15)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧