2015-11-02 55 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