1
\$\begingroup\$

I've been trying to implement a few interfaces for processing data. And most of the time I do new of container and return a smart pointer to this container. Something like this:

class GenericUtil
{
    private: 
        // Some members here

    public:
        unique_ptr<vector<string>> BreakStringOnDelimiter( string& dataStr );
};

But recently I came across "The c++ Programming Language" book and observed that Stroustrup seems to be suggesting to return containers just like that. But some other cases, he also demonstrates use of smart pointers for the same. So I have been just wondering what would be most efficient and maintainable way (plus a style which doesn't come as surprise to other fellow devs) of doing this?

unique_ptr<vector<string>> BreakStringOnDelimiter( string& dataStr );

or

vector<string> BreakStringOnDelimiter( string& dataStr );

or

vector<string>* BreakStringOnDelimiter( string& dataStr );

or something else?

Please suggest which one and why?

Thanks in advance!

\$\endgroup\$

closed as off-topic by vnp, Vogel612, 200_success Jan 28 '18 at 22:17

This question appears to be off-topic. The users who voted to close gave these specific reasons:

  • "Questions must involve real code that you own or maintain. Pseudocode, hypothetical code, or stub code should be replaced by a concrete implementation. Questions seeking an explanation of someone else's code are also off-topic." – 200_success
  • "Questions containing broken code or asking for advice about code not yet written are off-topic, as the code is not ready for review. After the question has been edited to contain working code, we will consider reopening it." – vnp, Vogel612
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ The vector<string> BreakStringOnDelimiter( string& dataStr ); is the most idiomatic way. In C++03 the compiler will elide the copy because of RVO. In C++11 this was made even more formal with Move Semantics. There is definitely no reason to use a smart pointer to hold a container. Containers and smart pointers are designed for memory management you don't need to use a smart pointer when the container is already doing the memory management (that just makes things slower). \$\endgroup\$ – Martin York Jan 29 '18 at 23:34
1
\$\begingroup\$

In C++ 11 you probably would use

vector<string> BreakStringOnDelimiter( const string& dataStr );

The container classes can be very efficiently move constructed (this is a new and smart feature of C++ 11 which can avoid temporary objects in many cases), which means that on return no expensive copy construction of the containers (and the strings in the container) is needed. Essentially only the some pointers are passed around on return.

Alternatively the solution with unique_ptr would also work, but is in my opinion not as good (and probably not really more efficient).

Given these alternative options, returning a bare pointer is not recommended.

For maximum efficiency you should consider using the emplace function when filling the vector. This avoids additional copies of string.

Also probably const string & as argument is better suited.

\$\endgroup\$
  • \$\begingroup\$ Even in C++-3 this was efficient. The RVO and NRVO optimizations built into the compiler would basically elide the copy. \$\endgroup\$ – Martin York Jan 29 '18 at 23:35
  • \$\begingroup\$ @MartinYork: true, even though it is guaranteed to happen only with C++17 and later. Although RVO and NRVO was implemented by virtually all compilers even before C++17. \$\endgroup\$ – Andreas H. Feb 5 '18 at 10:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.