模板类中有一个成员函数对string类型有特殊处理,如果不用特化是否还有其他办法?

fibbery 2008-09-28 02:55:34
模板类中有一个成员函数对string类型有特殊处理,如果不用特化是否还有其他办法?
template < typename T1,typename T2 >
class CMyClass;

当T2为std::string时,在CMyClass::func();中需要做一个特殊处理,请问,如果不用特化CMyClass类的办法,还有其他什么办法吗?
...全文
365 24 打赏 收藏 举报
写回复
24 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
fibbery 2008-10-06
最后,我采用了在模板类中增加一个模板函数和一个重载该模板函数的特化函数,这两个函数主要处理func中对于string与其它类型的不同部分!

即:
template < typename T1,typename T2 > 
class CMyClass
{
template<typename _Ty>
void diff(_Ty & t);
void diff(std::string & t);
public:
void func();//调用diff,当T2为string时调用的函数为void diff(std::string & t);
};
  • 打赏
  • 举报
回复
yshuise 2008-09-30
我实现了一个约束,dev测试通过:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

template<typename T3, typename T4>
struct must_be_same_type
{
enum { ret = 0 };
};
template<>
struct must_be_same_type<string, string>
{
enum { ret = 1 };
};
template < typename T1,typename T2 >
class CMyClass{
public:

void myfun(){
if(must_be_same_type<T2, string>::ret){
cout<<"很黄,很暴力"<<endl;
}else{
cout<<"很傻,很天真"<<endl;
}
}

};


int main(int argc, char *argv[])
{
CMyClass<int, int> a;
a.myfun();
CMyClass<int, string> b;
b.myfun();
system("PAUSE");
return 0;
}
  • 打赏
  • 举报
回复
waruqi 2008-09-29
[Quote=引用 16 楼 weiyijiji 的回复:]
14L的方法不错,可以根据函数优先级来选择函数重载.不过LZ要求的是成员函数,大概是没看到,改成成员函数的重载版本就可以了.
12L的也可以,不过我来觉得总感觉用运行时来判断不大舒服..
[/Quote]


“运行时” 在哪?
  • 打赏
  • 举报
回复
weiyijiji 2008-09-29
[Quote=引用 19 楼 waruqi 的回复:]
引用 16 楼 weiyijiji 的回复:
14L的方法不错,可以根据函数优先级来选择函数重载.不过LZ要求的是成员函数,大概是没看到,改成成员函数的重载版本就可以了.
12L的也可以,不过我来觉得总感觉用运行时来判断不大舒服..



“运行时” 在哪?
[/Quote]
typeid()
  • 打赏
  • 举报
回复
richbirdandy 2008-09-29
用成员函数调用非成员函数的确是一种方法
  • 打赏
  • 举报
回复
yshuise 2008-09-29
对可以用template设计模式完成这个任务:

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

template<typename T>
void fun(){}
template<>void fun<string>(){
cout<<"hello,wrod"<<endl;
}

template < typename T1,typename T2 >
class CMyClass{
public:
void myfun(){
//.....template模式
fun<T2>();
//.....template模式
};


int main(int argc, char *argv[])
{
CMyClass<int, string> aa;
aa.myfun();
system("PAUSE");
return 0;
}
  • 打赏
  • 举报
回复
matrixdwy 2008-09-28
直接重载这个函数就可以了,编译器似乎会自动匹配一个非模板的函数,避免使用模板
#include<iostream>
#include<string>
using namespace std;

template<class T>
void f(T) {
cout << "in template version" << endl;
}

void f(string) {
cout << "in string version" << endl;
}

int main() {
string test;
f(test);
f<string>(test);
cin.get();
}
  • 打赏
  • 举报
回复
fibbery 2008-09-28
三人行必有我师焉!众人的智慧就是不同凡响!
  • 打赏
  • 举报
回复
weiyijiji 2008-09-28
14L的方法不错,可以根据函数优先级来选择函数重载.不过LZ要求的是成员函数,大概是没看到,改成成员函数的重载版本就可以了.
12L的也可以,不过我来觉得总感觉用运行时来判断不大舒服..
  • 打赏
  • 举报
回复
scklotz 2008-09-28
通过引入第三个模板函数来完成对类型的特殊处理
  • 打赏
  • 举报
回复
scklotz 2008-09-28

#include <iostream>
#include <string>
using namespace std;

template <typename T>
void foo( const T& v )
{
cout << "logic2 simple: " << v << endl;
}

void foo( const string& v )
{
cout << "logic2 string: " << v << endl;
}

template <typename T1, typename T2>
class bar
{
public:
bar( const T1& v1, const T2& v2 ) : _t1(v1), _t2(v2)
{
func();
}

void func()
{
cout << "logic1: " << _t1 << endl;
foo<T2>( _t2 );
}

T1 _t1;
T2 _t2;
};


void main()
{
bar<int, float> c1(1, 10.0);
bar<float, float> c2(2.0, 20.0);
bar<float, string> c3(3.0, string("hello, world"));
}
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yshuise 的回复:]
C/C++ code#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>

using namespace std;
template < typename T1,typename T2 >
class CMyClass{
public:
void myfun(){
if( typeid(std::string) == typeid(T2))
{
cout<<"很黄,很暴力"<<endl;
}else{
cout<<"很傻,很天真"<<endl;
}

}
};



int _tmain(int …
[/Quote]
貌似有点意思
  • 打赏
  • 举报
回复
yshuise 2008-09-28
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>

using namespace std;
template < typename T1,typename T2 >
class CMyClass{
public:
void myfun(){
if( typeid(std::string) == typeid(T2))
{
cout<<"很黄,很暴力"<<endl;
}else{
cout<<"很傻,很天真"<<endl;
}

}
};



int _tmain(int argc, _TCHAR* argv[])
{
CMyClass<int, string> a;
a.myfun();
CMyClass<int, int> b;
b.myfun();

return 0;
}

以上在vc2003测试正确
  • 打赏
  • 举报
回复
richbirdandy 2008-09-28
[Quote=引用 10 楼 richbirdandy 的回复:]
把那个成员函数也改成模板函数
然后特化撒

这样也不用改其他的成员函数


C/C++ codetemplate <typename T1,typename T2>
class CMyClass
{
template <typename T>
void fun(){}

template <>
void fun<string>(){}
};
[/Quote]
理解错了 当我没说
  • 打赏
  • 举报
回复
richbirdandy 2008-09-28
把那个成员函数也改成模板函数
然后特化撒

这样也不用改其他的成员函数

template <typename T1,typename T2> 
class CMyClass
{
template <typename T>
void fun(){}

template <>
void fun<string>(){}
};
  • 打赏
  • 举报
回复
fibbery 2008-09-28
首先感谢各位!

我不想特化的原因是其他众多的成员函数均可以共用,如果特化这个类,所有的函数都要复制一份,如果将来修改,我觉得有些麻烦,容易出现版本不一致情况,不容易维护!

也不想继承,最好是类的名字一致,这样,对于客户代码没有什么感觉,就像在用同一个模板类!

继续探索探索,呵呵……
  • 打赏
  • 举报
回复
星羽 2008-09-28

函数好象不支持偏特话,所以你还是特化吧
template<typename t1, typename t2>
struct test {
};

template<typename t1>
struct test<t1, string> {

};
  • 打赏
  • 举报
回复
jieao111 2008-09-28
先说说你为什么不用特化吧
  • 打赏
  • 举报
回复
星羽 2008-09-28
就用特化吧
  • 打赏
  • 举报
回复
lyghe 2008-09-28

//无敌子类

template < typename T1,typename T2 >
class CMyClass
{virtual void func();}

template< typename T >
class CMyClass_string : public CMyClass<T, std::string>
{virtual void func();}
  • 打赏
  • 举报
回复
加载更多回复(3)
相关推荐
超级影响力的Java面试题大全文档 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承:  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。象的一个新类可以从现类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 3.封装:  封装是把过程和数据包围起来,数据的访问只能通过已定义的界面。面向象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的象,这些象通过一个受保护的接口访问其他象。 4. 多态性:  多态性是指允许不同类的同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。 5、String是最基本的数据类型吗?  基本数据类型包括byte、int、char、long、float、double、boolean和short。  java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类 6、int 和 Integer 什么区别  Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型 封装类 boolean Boolean char Character byte Byte short Short int Integer long Long float Float double Double  引用类型和原始类型的行为完全不同,并且它们具不同的语义。引用类型和原始类型不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型关。 7、StringStringBuffer的区别  JAVA平台提供了两个类:StringStringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用 StringBuffers来动态构造字符数据。 8、运行时异常与一般异常何异同?  异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 9、说出Servlet的生命周期,并说出Servlet和CGI的区别。  Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。 与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。 10、说出ArrayList,Vector, LinkedList的存储性能和特性  ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 11、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别。 EJB包括Ses
发帖
C++ 语言

6.2w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
帖子事件
创建了帖子
2008-09-28 02:55
社区公告
暂无公告