Bjarne Stroustrup 是不是错了!?请各位大小牛来帮我看看.....

redleaves 2004-08-13 12:23:40
BS在The Design and Evolution of C++ 15.4.1 中说,模板参数可以通过派生的方式来限定.比如:
template < typename _T >
class A {
public:
bool operator < ( const _T & );
};

template < class _C : A >
class vector {
...
};

可是我在其它的书上根本找不到这种用法,包括TCPL和ISO14882.用各种编译器也试了,不行.
是不是BS弄错了?
...全文
310 26 打赏 收藏 举报
写回复
26 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
redleaves 2004-08-13
TO Mephisto_76((望美人如梦)):
偶也觉得是这样.不过我看的是老裘翻译的版本,书里没有明确地写这是不是标准.只是说了它的好处和一堆坏处...
但因为书里对其它的一些特性如异常也是这样说的,就把我给搞晕了.

不知道有没有其它的办法来限定模板参数的父类(除了静态断言+转型测试这种,这种方法在父类为模板时,没法检测)
  • 打赏
  • 举报
回复
RookieStar 2004-08-13
楼主,DnE的原文意思很清楚了,他们曾经提出过这样的设想,但是批评更多,包括BS本人也持这种态度,所以最后没有在标准中出现。
  • 打赏
  • 举报
回复
Mephisto_76 2004-08-13
那是你看错了,应该是他(或者其它人)曾经提议过这样的解决方案,但是后来没有采纳这种限定,因为没有什么明显的好处。
  • 打赏
  • 举报
回复
lingjingqiu 2004-08-13
标准C++和编译器还是有区别的。这个你只有问BS才知道了。不过这个性能倒是有必要的,呵呵
  • 打赏
  • 举报
回复
redleaves 2004-08-13
鸡丁同志,偶是说没法解决我的实际问题,而不是说没解决我提出的问题啦...
你说的办法在MCD中其实都已经讲过了,我也试过了.但我的模板比较复杂,而且要结合我的第二个问题一起解决才OK.
无论如何还是多谢你啦!
  • 打赏
  • 举报
回复
Jinhao 2004-08-13
>>不知道有没有其它的办法来限定模板参数的父类(除了静态断言+转型测试这种,这种方法在父类为模板时,没法检测)
---
上面的代码都办到了啊

至于第二个问题确实想不出来。好象这样没有解法吧,其实helperA和helperB并不麻烦,只要把这两个的名字取好听点就可以了。
  • 打赏
  • 举报
回复
renheihei 2004-08-13
mark,全是高手
  • 打赏
  • 举报
回复
redleaves 2004-08-13
感谢鸡丁和心宇同志的热心帮助.对偶有很大的帮助,但是,遗憾的是,还是没有办法解决我的问题.....郁闷中.

还有,模板的非类型参数有什么限制?好像只能使用指针,引用和基本类型!?
  • 打赏
  • 举报
回复
freefalcon 2004-08-13
鸡丁对模板用得很熟了,赞一个 :)
  • 打赏
  • 举报
回复
Jinhao 2004-08-13
如果是非公有继承,我认为它使用于template A就是错的!
is-implemented-in-terms-of
class D:private urclass
D 不是 urclass
  • 打赏
  • 举报
回复
Jinhao 2004-08-13
心宇的已经足够了,但是我们还可以做进去
template<typename T>
class yourclassT
{
public:
typedef T value_type;
};

class urclass{};

namespace helper
{
template<typename U> double test(yourclassT<U>*);
int test(urclass*);

class nulltype{};

template<int, typename T>
struct x{};

template<typename T>
struct x<4, T>
{
typedef nulltype value_type;
};

template<typename T>
struct x<8, T>
{
typedef typename T::value_type value_type;
};
}

template<typename T>
class A
{
public:
typedef typename helper::x<sizeof( helper::test((T*)NULL)), T>::value_type value_type;
A(){}
};

template<typename T>
class A<yourclassT<T> >{
public:
typedef T value_type;
};


class B:public urclass
{};

template<typename T>
class C:public yourclassT<T>
{};

int main()
{
//A<int>a; //wrong, int does not derived from urclass
if(typeid(A<yourclassT<int> >::value_type)==typeid(int))
cout<<"it is int"<<endl;

if(typeid(A<B>::value_type)==typeid(helper::nulltype))
cout<<"no, we don't want it"<<endl;
if(typeid(A<C<int> >::value_type)==typeid(int))
cout<<"it is int"<<endl;
}
  • 打赏
  • 举报
回复
freefalcon 2004-08-13
用STL中常用的typedef

tempate<typename T>
yourclass {
public:
typedef T type;
};

class C : public yourclass<int>
{
typedef type yourclass::type type;

//...
}
  • 打赏
  • 举报
回复
redleaves 2004-08-13
TO freefalcon(心宇—小小菜鸟想高飞):
你的方法虽然可行,但这样还是用的以使用来限定参数的方法.并没有进行类型检查.

而 辣子鸡丁 同志的方法就不用,他是以静态造型来进行类型检查,可以确保一定从指定父类继承下来.但如果父类是非公有继承的话,造型就会失败...
  • 打赏
  • 举报
回复
redleaves 2004-08-13
OK,但还有一个问题,怎么取得父类(模板)的模板参数?
比如A<C<int> >中,类模板A不知道int这个类型.当然,你的例子里,可以用其它的方法得到.但如果把类C改成:
class C:public yourclassT<int>
{};
这时,父类的模板参数怎么得到呢?
  • 打赏
  • 举报
回复
freefalcon 2004-08-13
第一个问题,这样可以(可以按此思想进行拓展)

template<class T>
class Base
{
public:
typedef int Base_Identity;
};

template<class T>
class Derived : public Base<T>
{
};

class Other{};

template<typename T>
class A
{
typedef typename T::Base_Identity Internal_Identity;
};

void main()
{
A< Derived<int> > a; // ok
A<Other> b; // erroy
}
  • 打赏
  • 举报
回复
Jinhao 2004-08-13
第一个,改一下就可以了
template<typename T>
class yourclassT{};

class urclass{};

namespace helper
{
template<typename U> int test(yourclassT<U>*);
int test(urclass*);
}

template<typename T>
class A
{
enum { value = sizeof( helper::test((T*)NULL) ) };
public:
A(){}
};

template<typename T>
struct A<yourclassT<T> >{};


class B:public urclass
{};

template<typename T>
class C:public yourclassT<T>
{};

int main()
{
//A<int>a; //wrong, int does not derived from urclass
A<yourclassT<int> > b;//ok
A<B> c;//OK
A<C<int> > d; //ok
}
  • 打赏
  • 举报
回复
lgdpeter8 2004-08-13
mark,我暂时还不懂
  • 打赏
  • 举报
回复
redleaves 2004-08-13
TO Jinhao(辣子鸡丁)(不知被考试强奸多少次):
十分感谢你的回答!!

对于第一个解答:我在前面说了除了你说的这种方法外,还有什么其它的方法.因为,当父类为模板类时,这个办法就失效了.
就是说,在你的解答中,urclass为一个模板,我要求输入的类型都从这个模板继承,并且这个模板的参数是未知的.这时,enum { value = sizeof(static_cast<urclass*>((T*)(NULL)))};这句就没有办法写,因为urclass是一个不完整的类型.

对于第二个解答:你的做法不错,但不能根本解决问题,因为我是要避免使用时出现helperA,helperB这种名称,从而写起来更方便.我利用函数重载,宏,内嵌类可以勉强实现,但有很多限制.
  • 打赏
  • 举报
回复
Jinhao 2004-08-13
你这样是在定制限制,不知道为什么要这么做,如果你的代码是给别人用,应该用文档来说明
  • 打赏
  • 举报
回复
Jinhao 2004-08-13
第一个问题
>>如果我现在想限定传入类型参数只能是我自己写的类(模板)和它的派生类,那应该怎么写呢?
-----------
template<typename T>
class yourclassT{};

class urclass{};

template<typename T>
class A
{
enum { value = sizeof(static_cast<urclass*>((T*)(NULL)))};
};

template<typename T>
struct A<yourclassT<T> >{};

class B:public urclass
{};

int main()
{
A<int>a; //wrong, int does not derived from urclass
A<yourclassT<int> > b;//ok
A<B> c;//OK
}

对于第二个问题也有解决的办法,定义一个helper template,然后利用特化
template<typename T, int val>
struct helperA{};

template<int val, typename T>
struct helperB{};

template<typename T>
A{};

template<int val, typename T>
class A<helperB<val, T> >{};

template<typename T, int val>
class A<helperA<T, val> >{};

A<helperA<int, 10> > a1;
A<helperB<10, int> > a2;
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
C++ 语言
加入

6.2w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
申请成为版主
帖子事件
创建了帖子
2004-08-13 12:23
社区公告
暂无公告