我得到了以下代码(不要争论它是否有意义,它只是一个最小的例子):
struct X{
template <typename T>
T foo(){ return T(); }
};
template <typename T>
struct Z{
virtual X bar(){
bar().foo<int>();
return X();
}
};
Run Code Online (Sandbox Code Playgroud)
它不能在我的g ++ 4.6.3上编译.该行bar().foo<int>();给出以下错误:
error: expected primary-expression before ‘int’
error: expected ‘;’ before ‘int’
Run Code Online (Sandbox Code Playgroud)
当我第一次将bar()的结果保存在局部变量中时,它就可以工作,即如果我替换bar().foo<int>()为
X x = bar();
x.foo<int>();
Run Code Online (Sandbox Code Playgroud)
然后它工作.如果我现在声明局部变量auto而不是X,即:
auto x = bar();
x.foo<int>();
Run Code Online (Sandbox Code Playgroud)
然后我收到和以前一样的错误.如果我从类Z中删除type参数(即使它成为常用而不是模板类),那么它再次起作用.
如果我使用classtype X而不是intfoo的类型参数,即foo<X>,我收到以下错误:
expected primary-expression before ‘>’ token
expected primary-expression before ‘)’ token
Run Code Online (Sandbox Code Playgroud)
我真的无法在这里发现错误.请帮忙!
你需要证明有问题的类型是可以接受的(这是我认为是GCC中的一个错误的解决办法,请参阅下面的编辑),即
struct X{
template <typename T>
T foo(){ return T(); }
};
template <typename T>
struct Z{
virtual X bar(){
bar().template foo<int>();
return X();
}
};
Run Code Online (Sandbox Code Playgroud)
基本问题与解析有关,因为可以通过多种方式解析显式模板实例化.有趣的一点(我认为)位于14.2p4,它如下:
当一个构件模板特的名称出现之后
.或->在后连接的x表达式或之后 嵌套名称-SPECI音响ER在一个合格音响ED-ID,和所述的对象或指针表达后连接的x表达或 嵌套名称SPECI音响ER在quali fi ed-id依赖于模板参数(14.6.2)但不引用当前实例化的成员(14.6.2.1),成员模板名称必须由关键字预先固定template.否则,假定该名称命名非模板.
如果我没有严重错误,Z<T>::bar 确实取决于模板参数,但同时它确实引用了当前的实例化,因此我倾向于认为该标准不需要像GCC那样的资格.当多个编译器的结果相互矛盾时,我倾向于使用Comeau,在这种情况下,表示不需要template限定符.
| 归档时间: |
|
| 查看次数: |
174 次 |
| 最近记录: |