2012-12-07 56 views
3

我正在用Qt編寫圖像查看器。 我試圖做的頭文件如下:static const std :: vector

int zooms[] = {1,2,3,4,5,6,7,8,9,10}; 
const std::vector<int> mZoomLevels(zooms.begin(),zooms.end()); 

不過,我得到以下錯誤:

request for member 'begin' in zooms which is of non-class type 'int[10]' request for member 'end' in zooms which is of non-class type 'int[10]'

有誰知道如何

class ImageModel 
{ 


private: 
    const static std::vector<int> mZoomLevels; 

} 
在源文件中

初始化這個靜態const私有成員?

+0

如果是這樣'常量的std ::矢量 ImageModel :: mZoomLevels(...) '? –

回答

5

平面陣列不具有成員函數。我相信你正在尋找這樣的:

int zooms[] = {1,2,3,4,5,6,7,8,9,10}; 
const std::vector ImageModel::mZoomLevels(zooms, zooms + 10); 
+0

謝謝你的快速回答! – Cristi

5

數組沒有beginend成員。您可以使用begin數組名和數組名加長度結束:

const std::vector mZoomLevels(zooms, zooms+10); 

在C++ 11,可以使用std::beginstd::end,像這樣:

const std::vector mZoomLevels(std::begin(zooms), std::end(zooms)); 

在這兩種情況下,聲明zooms數組文件是一個好主意 - static或將其隱藏在名稱空間中,以確保其名稱不會「污染」全局名稱空間。

+2

如果你有C++ 11,並且你想初始化向量,就不需要創建數組,只需要使用* list-initialization *:const std :: vector ImageModel :: mZoomLevels {1,2,3 ,4 ...};' - 無代碼,你刪除一個不需要的數組。那就是如果你真的想要使用'std :: vector '......我不太確定... –

1

zooms是一種C型陣列,它沒有成員和方法,即zooms.beginzooms.end是沒有意義的。如果使用C++ 11兼容編譯器,請嘗試使用std::begin(zooms)std::end(zooms)

1

正常C++數組不能有成員。但是,您正在尋找靜態分派,並且通過參數類型重載解析可以正常工作。所以C++ 11提供了非成員函數std::beginstd::end。 (這已經提到)

習慣的最佳實踐調用非成員函數如下(它確實有助於爲你寫的通用模板代碼):

using std::begin; 
using std::end; 

const std::vector mZoomLevels(begin(zooms), end(zooms)); 

這將正常工作沒有問題是容器zooms是什麼類型,並且如果zooms具有一些自定義類類型,它將利用ADL(依賴於參數的查找,有時稱爲Koenig查找)在同一名稱空間中查找beginend的實現。

BTW,std::beginstd::end由C++ 11提供的,但你可以寫你自己很輕鬆地爲早期版本:

template <typename T, size_t N> 
T* begin(T (&a)[N]) { return a; } 

template <typename T, size_t N> 
T* end(T (&a)[N]) { return a + N; } 
+0

爲什麼使用''?這裏不需要ADL。 – Puppy

+0

@DeadMG:爲什麼不使用''?如果他養成了正確的做法,在模板中使用它時不會突然出現問題。 –

+0

模板不會改變任何內容。他在本地數組上調用它 - 「std :: begin」,並且「std :: end」將始終被選中。 – Puppy

1

我會在這裏遵循不同的方法取決於您是否有訪問到C++ 11或不。在C++ 03中,我會使用普通數組(因爲它是const),甚至可能不在類中,但在實現文件的私有名稱空間中(因爲它是私有的,假設只有一個翻譯單位的成員定義爲ImageModel)。

// cpp 
namespace { 
    static int gZoomLevels[] = { 1, 2, ... }; 
} 

如果你真的想繼續使用std::vector<int>的方法,我將創建一個翻譯單元定義成員的輔助功能,並用它來創建std::vector,且不會與靜態的持續時間不同的變量:

namespace { 
    static std::vector<int> chooseANameForInitializer() { 
     int data[] = { 1, 2, 3 }; 
     return std::vector<int>(data, data + (sizeof data/sizeof *data)); 
    } 
} 
const std::vector<int> ImageModel::mZoomLevels = chooseANameForInitializer(); 

在C++ 11中,我會使用std::array<int,...>來代替,因爲這樣可以避免動態分配和額外間接成本。當然,這不是一個好的收益,但是當你不需要它提供的任何功能的時候,沒有任何意義。

class ImageModel 
{ 
private: 
    static const std::array<int,10> mZoomLevels; 
}; 
// cpp: 
const std::array<int,10> ImageModel::mZoomLevels = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

同樣,如果你堅持有std::vector<int>那麼你可以使用列表初始化

const std::vector<int> ImageModel::mZoomLevels{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
相關問題