1

我有一个包含元素数组的类,我想给它一个GetSize成员函数。但是我应该给那个函数什么返回类型呢?

我正在使用 pimpl 习惯用法,因此在头文件中不知道实现将使用什么来存储元素。所以我不能只说std::vector<T>::size_type,例如:

class FooImpl;

class Foo {
  FooImpl* impl_;
public:
  TYPE GetSize(); // what TYPE??
};
4

4 回答 4

1

如果客户端代码只能看到Foo(这是 pimpl idiom 的目的),那么size_type在具体实现中定义一个特定的就没有用 - 无论如何客户端都不会看到/访问它。标准容器可以做到这一点,因为它们建立在所谓的“编译时多态性”之上,而您专门尝试使用 [可能] 运行时实现隐藏方法。

在您的情况下,唯一的选择是选择“对于所有可能的实现应该足够”的整数类型(例如unsigned long,例如)并坚持下去。

另一种可能性是使用该uintptr_t类型,如果它在您的实现中可用(它在 C99 中标准化,但在 C++ 中没有)。这个整数类型应该覆盖程序可用的整个存储地址范围,这意味着它总是足以表示任何内存容器的大小。请注意,其他发帖人经常使用相同的逻辑,但错误地得出结论,此处使用的适当类型是size_t. (这通常是由于缺乏非平面内存模型实现经验的结果。)如果您的容器始终基于物理数组,size_t则可以使用。但是,如果您的容器并不总是基于数组,size_t甚至不是在这里使用的正确类型,因为它的范围通常小于非连续(非基于数组)容器的最大大小。

但无论如何,无论您最终使用什么大小,最好将其隐藏在 typedef-name 后面,就像在标准容器中所做的那样。

于 2010-02-01T16:38:43.780 回答
1

C++ 中大小的通用类型是 size_t。我会用那个。

我的意思是非技术意义上的通用。这与模板无关。

以前好像出现过这样的情况:我什么时候应该使用 std::size_t?

编辑

经过多次讨论,我将稍微修改我的答案。

如果 size_t 与指针一样宽,则使用 size_t。如果不是,请使用与指针宽度相同的无符号整数。

于 2010-02-01T17:02:54.787 回答
0

size_type 通常用于隐藏整数类型(short vs. long vs. long long 等)。只需定义自己的Foo::size_type.

于 2010-02-01T16:33:35.963 回答
0

您可以遵循 STL 的领导并制作size_type一个typedef依赖于FooImpl

template<typename T> class s_type {
    public:
    typedef size_t type; // good default
};

class FooImpl;

// I'm only doing this specialization to show how it's done
// not because I think it's needed.  In general I'd use size_t.
template<> class s_type<FooImpl> {
    public:
    typedef uintptr_t type;
};

class Foo {
  FooImpl* impl_;

  public:
  typedef size_type s_type<FooImpl>::type;
  size_type GetSize();
};
于 2010-02-01T20:53:31.560 回答