3

我正在用 Qt 编写一个图像查看器。我正在尝试在头文件中执行以下操作:

class ImageModel
{


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

}

在源文件中:

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

但是我收到以下错误:

在非类类型“int [10]”的缩放中请求成员“开始” 在非类类型“int [10]”的缩放中请求成员“结束”

有谁知道如何初始化这个静态常量私有成员?

4

5 回答 5

5

普通数组没有成员函数。我相信你正在寻找这个:

int zooms[] = {1,2,3,4,5,6,7,8,9,10};
const std::vector ImageModel::mZoomLevels(zooms, zooms + 10);
于 2012-12-07T14:44:21.067 回答
5

数组没有beginend成员。您可以使用数组名称begin和数组名称加上长度作为结尾:

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

在 C++11 中,您可以使用std::beginand std::end,如下所示:

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

在这两种情况下,最好将zooms数组文件声明为静态或将其隐藏在命名空间中,以确保其名称不会“污染”全局命名空间。

于 2012-12-07T14:44:28.647 回答
1

zooms 是一个 C 风格的数组,没有成员和方法,也就是说zooms.beginzooms.end没有任何意义。如果您使用与 C++11 兼容的编译器,请std::begin(zooms)尝试std::end(zooms)

于 2012-12-07T14:45:56.103 回答
1

普通 C++ 数组不能有成员。但是,您正在寻找静态分派,并且可以通过参数类型进行重载解析。所以 C++11 提供了std::beginstd::end成员函数。(这已经提到过。)

习惯如下调用非成员函数的最佳实践(这对您编写通用模板代码很有帮助):

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

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

无论容器是什么类型,这都能正常工作,并且如果有一些自定义类类型zooms,它将利用 ADL(依赖于参数的查找,有时称为 Koenig 查找)来查找相同命名空间中的实现。beginendzooms

顺便说一句,std::beginstd::endC++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; }
于 2012-12-07T14:48:23.633 回答
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,...>改用,因为这样可以避免动态分配和额外间接的成本。当然,这不是一个很大的收获,但是std::vector<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>then 您可以使用list-initialization

const std::vector<int> ImageModel::mZoomLevels{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
于 2012-12-07T15:00:56.563 回答