2011-05-13 141 views
8

我不明白为什么这并不编译:模板模板类

struct A 
{}; 

template<class T> 
struct B 
{}; 

template<template<class> class T1, class T2> 
struct C 
{}; 

int 
main (int ac, char **av) 
{ 
    typedef B<double> b;    //compiles 
    typedef B<const double> b_const; //compiles 
    typedef B<A> ba;     //compiles 
    typedef B<const A> ba_const;  //compiles 

    typedef C<B,double> c1;   //compiles 
    typedef C<B,const double> c2;  //compiles 
    typedef C<const B,double> c3;  //ISO C++ forbids declaration of ‘type name’ with no type 
} 

(我找到参照标准有点神秘)

我有什么改变,使其编译?

编辑:

编译器的细节(这好像是培训相关):

Using built-in specs. 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) 

EDIT2:

通过交代的手段,我试图做这样的事情:

template<template<class> class TheContainer, class T> 
struct Iterator 

template<class T> 
struct Container 

typedef Iterator<Container, double> iterator; 
typedef Iterator<const Container, double> const_iterator; 

非模板容器的技术可在此升压文档的末尾找到:http://www.boost.org/doc/libs/1_46_1/libs/iterator/doc/iterator_facade.html

我猜测解决方案并不是为了模板。回想起来,这似乎很明显。

+0

这篇文章有一个很棒的主题:) – Laserallan 2011-05-13 23:03:48

+0

@Laserallan它使我成为Perl的口号 – Tom 2011-05-13 23:09:35

+1

“我需要改变什么才能编译它?”显然,你需要删除最后一个typedef。更严重的是,你想通过这样做完成什么? – 2011-05-14 00:24:54

回答

4

C的第一个参数不是一个类型,因此传递一个const类型作为arg是没有意义的。模板不能是常量或非常量,只有类型可以是常量或非常量。 const B甚至意味着什么?

const int是有意义的。 const vector<int>是有道理的,vector<const int>也是如此。但是const vector是什么意思?

(捏的盐警告:我没有看到这个问题之前甚至不知道模板的模板类)

为了使这更具体,想象B和C是:

template<class T> 
struct B 
{ 
     T t; 
};  

template<template<class> class T1, class T2> 
struct C 
{ 
     T2 t2; 
     T1<T2> t1; 
}; 

C2将是类型

C<B,const double> 
==> struct { const double t2; T1<const double> t1;} 
==> struct { const double t2; struct { const double b; } t1;} 

什么,你会期望C3是吗? t1本身是const,而t1.b是非const?我想这是有道理的。

+0

谢谢,是的,现在看起来很明显。我需要明确地输出我想要的模板 – Tom 2011-05-14 00:51:44

+0

谢谢你让我知道模板模板! – 2011-05-14 01:08:11

1

我猜B不能是常量,因为此时它没有实型,编译器也不知道什么是const。除了离开const之外,我无法想出正确编译的解决方案,因为模板模板对大脑来说真的很痛苦。

2

这个确切的代码在VS2010中编译。我不知道你的编译器,但我建议你检查编译器开发者的bug数据库,如果没有注册这样的错误。

我会在GCC中试试看。


Ok GCC(4.5.1)确实会给出错误。我想我们必须等待具有标准知识的人员了解它是标准行为还是错误。


CLang(2.8)确实给出了相同的错误(使用完全相同的消息)。

+0

感谢您试用它 - 我发布了我的gcc -v。我现在将看看bug数据库 – Tom 2011-05-14 00:15:37

+0

没问题。我开始搜索,但是这个错误信息在很多其中找不到类型的情况下使用,所以很难找到一个错误。我想也许VS2010太宽松了。很难知道没有标准的知识。 – Klaim 2011-05-14 00:20:22