我有一个包含元素数组的类,我想给它一个GetSize
成员函数。但是我应该给那个函数什么样的返回类型?
我正在使用pimpl习语,因此在头文件中不知道实现将用于存储元素的内容。所以我不能只说std::vector<T>::size_type
,例如:
class FooImpl;
class Foo {
FooImpl* impl_;
public:
TYPE GetSize(); // what TYPE??
};
答案 0 :(得分:1)
如果客户端代码只能看到Foo
(这是pimpl习语的目的),那么在具体实现中定义特定的size_type
是没有用的 - 它将不可见/无论如何,客户都可以访问。标准容器可以做到这一点,因为它们构建在所谓的“编译时多态”上,而您特别尝试使用[可能]运行时实现隐藏方法。
在您的情况下,唯一的选择是选择“应该足以满足所有可能的实现”的整数类型(例如unsigned long
)并坚持使用它。
另一种可能性是使用uintptr_t
类型,如果它在您的实现中可用(它在C99中标准化,但在C ++中没有标准化)。该整数类型应该涵盖程序可用的整个存储地址范围,这意味着它总是足以表示任何内存容器的大小。请注意,其他海报通常使用相同的逻辑,但错误地得出结论:此处使用的适当类型为size_t
。 (这通常是由于缺乏非平坦内存模型实现的经验。)如果您的容器始终基于物理数组,size_t
将起作用。但是,如果您的容器并不总是基于数组,那么size_t
甚至不是远程正确的类型,因为它的范围通常小于非连续(非基于数组)的最大大小容器
但无论如何,你最终使用的是什么尺寸的regardelss,最好将它隐藏在typedef-name后面,就像在标准容器中完成一样。
答案 1 :(得分:1)
C ++中大小的泛型类型是size_t。我会用它。
我的意思是非技术性的通用。这与模板无关。
之前看起来像这样:When should I use std::size_t?
修改的
经过多次讨论,我将略微修改我的答案。
如果size_t与指针一样宽,请使用size_t。如果不是,请使用与指针宽度相同的无符号整数。
答案 2 :(得分:0)
size_type通常用于隐藏整数类型(短对长与长对等)。只需定义自己的Foo::size_type
。
答案 3 :(得分: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();
};