2017-03-02 49 views
1

當我嘗試在GCC上編譯我的程序時遇到了一個問題,並且有興趣知道如何使用C++ 11的初始化語法e.g. struct { int a; int b} my_struct {1, 2}可移植地初始化一個繼承的POD結構。該問題可以用下面的代碼在MSVC上編譯得很好來代表。如何初始化可移植派生類中的繼承模板化POD結構?

#include <iostream> 

template <typename A> 
struct base { 
A a; 
}; 

template <typename A> 
class derived : public base<A> { 
public: 
    derived(); 
}; 

template <typename A> 
derived<A>::derived() : base {1} { 

    std::cout << "Constructed " << a << std::endl; 
} 

int main() { 
    derived<int> d1; 
} 

然而,GCC與C++ 14啓用大致指出derived<A>沒有任何字段 '基礎'。所以我嘗試了以下更改。

template <typename A> 
derived<A>::derived() : base<A> {1} { 

    std::cout << "Constructed " << a << std::endl; 
} 

GCC現在可以識別base<A>derived<A>罰款的領域,但指出a未在此範圍內聲明。

有趣的是,這個改變現在不能在MSVC上編譯,並且狀態「'{':缺少函數頭(舊式正式列表?)」。

在這一點上,我不知道如何以符合標準的方式編寫這個。

謝謝。

+0

它編譯我的VS15 .... – ZivS

+0

...但不是他的最後一個例子,在VS15這隻能更換時':基地'通過':base'。 – zett42

回答

0

這使你的最後一個例子的工作:

std::cout << "Constructed " << this->a << std::endl; 

演示:http://coliru.stacked-crooked.com/a/fe9715a447ffbea1

起初我無法編譯MSVC++ 2015年(更新一)下。安裝update 3後編譯好。

+0

爲什麼在GCC上這是必要的?無論如何,可移植性問題仍然存在。 – jezzi23

+1

看來你已經找到了一個幾乎不受任何一個編譯器支持的邊界情況。 – zett42

+0

@ zett42您正在使用哪個VS15更新? – ZivS

0

C++ 17將支持這在某種形式:

表格aggregate_initialization:

每個直接公共的基礎上,(因爲C++ 17)陣列元件,或非靜態類構件,在數組下標/外觀在類定義中的順序是從初始化程序列表的相應子句進行復制初始化的。

// aggregate 
struct base1 { int b1, b2 = 42; }; 
// non-aggregate 
struct base2 { 
    base2() : b3(42) {} 
    int b3; 
}; 
// aggregate in C++17 
struct derived : base1, base2 { int d; }; 
derived d1{ {1, 2}, { }, 4}; // d1.b1 = 1, d1.b2 = 2, d1.b3 = 42, d1.d = 4 
derived d2{ { }, { }, 4}; // d2.b1 = 0, d2.b2 = 42, d2.b3 = 42, d2.d = 4 

與此同時,一個標準的方式是:

template <typename A> 
    derived<A>::derived() { 
     this->a = 1; 
}