Do I really need to return Type::size_type?

点点圈 提交于 2021-01-27 06:42:57

问题


I often have classes that are mostly just wrappers around some STL container, like this:

class Foo {
public:
  typedef std::vector<whatever> Vec;
  typedef Vec::size_type size_type;
  const Vec& GetVec() { return vec_; }
  size_type size() { return vec_.size() }
private:
  Vec vec_;
};

I am not so sure about returning size_type. Often, some function will call size() and pass that value on to another function and that one will use it and maybe pass it on. Now everyone has to include that Foo header, although I'm really just passing some size value around, which should just be unsigned int anyway ...? What is the right thing to do here? Is it best practice to really use size_type everywhere?


回答1:


STL defines these types as an abstract interface for containers. It is intended to support any type of backing storage. That might be NUMA or disk-backed storage, where size_type and ptr-type are different from those for system memory. Or - in a NUMA architecture - it might be a specific memory node that's fast, and can work with a very small size_type and ptr_type - which is a relevant optimization on many architectures.

At least, that were the design goals, also driven by anticipation what could be platforms supporting C++. Some early concessions also allowed shortcuts for STL implementers that basically disable this flexibility, and I've never worked with an STL implementation that made use of this. I'd say that's because linear memory access has become much less of a problem, and STL development at that level isn't actually easy.

Still, how much does it hurt you? It would be the right thing to do.




回答2:


It should be vector<>::size_type like you have, this is the most correct way.

That said, I know many people, including myself, will just use size_t instead. Although it's not mandated to be the same, vector<>::size_type is size_t for every implementation I know. You should be fine with that.




回答3:


Actually, it should be size_t and not unsigned int, for 64-bit compatibility. As wrapper class writer, I would return size_type. As class client, I would cast it to appropriate type (size_t), if it is more convenient.




回答4:


I am not so sure about returning size_type. Often, some function will call size() and pass that value on to another function and that one will use it and maybe pass it on. Now everyone has to include that Foo header...

It's fine to return the size_type, but this doesn't mean another function should necessarily take the same size_type as typedeffed in your class. There exist conversions between integral types. Be brave and just use size_t.

You can't overload functions anyway so that there would be one that works with size of vector, another for size of deque etc, just in case they all happen to be using a different size_type (which the standard probably permits). - But you could also use templates, if possible, to deduce the correct size_type to use from the argument.




回答5:


One option you could consider is inheriting from std::vector :

typedef std::vector<whatever> Foo_Vec;

class Foo : public Foo_Vec
{
public:
    const Foo_Vec &GetVec() { return (Foo_Vec&)*this; }
};

I am by no means saying this is the best approach, as it can introduce issues that wouldn't occur by having a private member or inheriting from private Foo_Vec, as public Foo_Vec exposes all methods on std::vector to Foo. Moreover, std::vector does not have a virtual destructor, so if you attempt to clean up a collection of std::vector's with a Foo tucked in there, it won't get cleaned up entirely. I'm just throwing it out there.

As other answers suggest, you should use size_t or size_type instead of unsigned int for 64-bit compatibility. Otherwise, in a future 64-bit build, your std::vector could have more than 232 items, but the size value would be truncated, leading to bugs.



来源:https://stackoverflow.com/questions/2693665/do-i-really-need-to-return-typesize-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!