首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

linux C++ 惊天大发现,该怎么处理

2013-08-01 
linux C++ 惊天大发现namespace templatetest{class Base{public:virtual ~Base(){}virtual void show()

linux C++ 惊天大发现

namespace templatetest
{
class Base
{
public:
virtual ~Base()
{}
virtual void show() = 0;
};

template<class T>
class A : public Base
{
T str;
public:
A(T v):str(v){}
virtual void show()
{
cout<<str<<endl;
}
};
template<class T>
class B : public A<T>
{
public:
B(T v):A(v)
{}
};

class C : public B<int>
{
public:
C(int i):B(i){}
};

void test()
{
A<char*> a("abc");
a.show();
B<int> b(123);
b.show();
C c(123);
c.show();

Base *bb = &c;
bb->show();
}
}


此段代码在Microsoft Visual Studio.Net(VS2010/2008)下运行正常,在linux下GCC编译不通过
然后改成

namespace templatetest
{
class Base
{
public:
virtual ~Base()
{}
virtual void show() = 0;
};

template<class T>
class A : public Base
{
T str;
public:
A(T v):str(v){}
virtual void show()
{
cout<<str<<endl;
}
};
template<class T>
class B : public A<T>
{
public:
B(T v):A<T>(v)
{}
};

class C : public B<int>
{
public:
C(int i):B<int>(i){}
};

void test()
{
A<char*> a("abc");
a.show();
B<int> b(123);
b.show();
C c(123);
c.show();

Base *bb = &c;
bb->show();
}
}

就可以了


我自己想出来的,怎么样,算不算大发现?
[解决办法]
看了一个VS里边的stl实现,都用的是
B(T v):A(v)这样的

不过VS里B(T v):A<T>(v)这样也能编译通过.

楼主继续总结linux和Windows下编译不同啊,
比起就讲讲哪些API函数不一样,这个更有意义.
------解决方案--------------------


:A<T>(v)
是正确用法。A不是类,而是模板。

不过一般我写这种类模板都会:
typedef A<T> base_type;
typedef B<T> this_type;

B(T v):base_type(v)

[解决办法]
把有限的生命浪费在品尝/品鉴无穷多种的语法糖中,我认为不值当。

[解决办法]
楼主的代码我倒没测试过,不过现在GCC对injected-class-name的支持应该有不少改进,至少我现在很少看到有常用的语法它不支持.但GCC过不了的代码还是很多.比如:
template<class T>struct A{};
template<class T>
struct B:A<T> {
typename B::A<typename B::A> b;
};
有些GCC能支持的特性,其它编译器反而不支持.
这种injected-class-name的查找,尤其是和模板联系起来的时候,各家实现都不一样.总的来说,VC,ICL在这方面的支持要好一些.
而且这类语法比较诡异,却很常用.好在常用的那些形式,行为比较统一...

热点排行