2015-11-02 56 views
12

我有以下一段代码,它不在Visual C++ 2015下编译,但在GCC 4.8.4下。我想知道哪个是对的?有问题的代码是在这里如下:将说明符覆盖为模板参数 - 是否有效?

template <class T> class ATemplate; 
template <class R, class A1> 
    struct ATemplate<R(A1)>{ }; 

int main() 
{ 
    ATemplate<void(int)> x; 
// ATemplate<void(int)override> y; //---Does not compile!!! 
    return 0; 
} 

这是错误的下面这里(或常量)使用覆盖为符。 GMock库中存在类似的代码,其中宏扩展用于生成模板参数(包括覆盖)以及实际函数签名。除去注释掉线时

的Visual C++ 2015产生以下错误:

x.cpp(11): error C2062: type 'int' unexpected 
x.cpp(11): error C2976: 'ATemplate': too few template arguments 
x.cpp(4): note: see declaration of 'ATemplate' 
x.cpp(11): error C2079: 'y' uses undefined class 'ATemplate' 

一下面提及的是覆盖处于自由函数(有效点)的上下文中无意义的答案 - 执行此这意味着GCC在这里是错误的。 常量说明符在这种情况下也是没有意义的(对于自由函数),但是允许(通过VC++)?此外,它还提到虚拟说明符应该只存在于声明中 - 这对这种情况没有任何影响(因为没有定义)。对于虚拟关键字,可以在派生中省略,因为代码编译没有区别,但对于覆盖情况,它不是好的,因为它有很大的区别。

当使用返回类型(ArgType ARG)...可能const或重写符作为宏参数(像GMock一样),由VCC施加的限制导致该代码不编译(显然为锵的情况下也是如此) 。哪个是对的?

该标准没有说明覆盖说明符不应该在这个上下文中使用(模板参数的上下文吗?),是吗?

+0

来看由票我可能失去了一些东西很明显,但如果是你想要覆盖的功能? –

+0

@KarolyHorvath这是不相干的 –

+0

@KarolyHorvath,是的,这是无关紧要的。发布的代码很少,并产生错误。 –

回答

8

这是一个g ++的bug。

该标准允许的virt说明符仲丁基在两个产生:在一个函数的定义的(仅用于virtual成员函数定义),并在构件声明符。你的语境既不是。

的海湾合作委员会的错误行为更短的演示:

void foo(void) override;   // g++ rejects with message: 
            // virt-specifiers in 'foo' 
            // not allowed outside a class definition 
void (*bar)(void) override;  // g++ erroneously accepts 
typedef void baz(void) override; // g++ erroneously accepts 
5

按照标准override符是上下文敏感,具有特殊的意义只有时,它的成员函数声明后使用;否则,它不是保留关键字。

所以我会说,你的第二个例子中的代码似乎毫无意义。

我试着用gcc-5.1.0(带有-S标志)编译你的两个例子,它们导致完全相同的程序集。

它不clang-3.7.0下编译导致以下错误:

test.cpp:11:23: error: expected '(' for function-style cast or type construction 

Pracitcally这意味着你不应该以这种方式使用的覆盖。

+1

这实际上是什么意思? –

+0

@WernerErasmus这意味着你不应该这样使用:) –

+0

错误。你的例子和我的不一样。 –

2

9.2类成员(N4140草案)

virt-specifier-seq: 
    virt-specifier 
    virt-specifier-seq virt-specifier 
virt-specifier: 
    override 
    final 

[9.2/8]

A virt-specifier-seq shall contain at most one of each virt-specifier. A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).

所以据我所看到的,override不能被应用到自由函数,所以我不希望它被允许在自由函数的签名/类型中(即使它是const类型的一部分)。

+0

覆盖在上面的上下文没有出现在函数的定义中(因为我没有指定定义),但是我明白了你的观点 - 尽管如此,在派生案例中忽略虚拟并不重要,但省略了覆盖,因此这不能被视为相同。 –

+0

@WernerErasmus不完全是我的意思,编辑澄清(我希望:)) – melak47