C++ teleplate非类型的函数模板参数(4.2节,4.3节)

前面说到了类模板可以定义非类型参数,其实函数模板也可以定义非类型参数。例如,下面的函数模板定义了一组用于增加特定值的函数:

template<typename T, int VAL>

T addValue(T const& x)

{

         return x + VAL;

}

如果需要把函数或者操作用作参数的话,那么这类型函数就是相当有用的。譬如,借助于标准模板库(STL),你可以传递这个函数模板的实例化给集合中的每一个元素,让它们都增加一个整数值:

std::transform(source.begin(),        //源集合的起点
               source.end(),        //源集合的终点    
               dest.begin(),        //目标集合的起点
               addValue<int, 5>);    //操作(或者函数)

在上面的调用中,最后一个实参实例化了函数模板addValue(),它让int元素增加5.源集合source中的每一个元素都会调用实例化后的addValue函数,并把调用结果放入上档集合dest.

下面看具体的示例:

//addval.h
#ifndef ADDVAL_H
#define ADDVAL_H
#include <iostream>

template<typename T, int VAL>
T addValue(T const &x)
{
    std::cout << "x====" << x << " VAL===" << VAL << std::endl;
    return x + VAL;
}

#endif // ADDVAL_H

 

 

//addvaltest.cc
#include "addval.h"
#include <iostream>


//template<typename T, int VAL>
//T addValue(T const &x)
//{
//    return x + VAL;
//}

void call_addValue()
{
    addValue<int, 5>(42);
}

template <typename IT, typename OP>
void transform(IT beg, IT end, IT to, OP op)
{
    while (beg != end){
        *to++ = op(*beg++);
    }
}

#if 1
int main()
{
    call_addValue();
    std::cout << "===================" << std::endl;
    int m[] = {1, 2, 3, 4, 5, 6};
    transform(m, m + 6, m, addValue<int, 5>);
    for(int i = 0; i < 6; ++i)
        std::cout << "m[" << i << "]=====" << m[i] << std::endl;
    return 0;
}

#endif

 

非类型模板参数的限制

非类型模板参数是有限制的,通常而言,它们可以是常整数(包括枚举值)或都指向外部链接对象的指针。

浮点数和类对象(class-type)是不允许作为非类型模板参数的:

template<double VAT> //ERROR:浮点数不能作为非类型模板参数
double process(double v)
{
	return v * VAT;
}

template<std::string name> //ERROR:类对象不能作为非类型模板参数
class MyClass {
	...
};

    之所以不能使用浮点数(包括简单的常量浮点表达式)作为模板实参是有历史原因的。然而,该特性的实现并不存在很大的技术障碍;因此,将来的C++版本可能会支持这个特性。由于字符串文字是内部链接对象(因为两个具有相同名称但处于不同模块的字符串,是两个完全不同的对象),所以你不能使用它们来作为模板实参:
template<char const *name>
class MyClass {
    ...
};
char const *s = "hello";
MyClass<s> x;    //s是一个指向内部链接对象的指针

然而,你可以这样使用:
template <char const* name>
class MyClass{
    ...
};
extern char const s[] = "hello";
MyClass<s> x;  //OK
全局字符数组s由"hello"初始化,是一个外部链接对象。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值