1

I would like to use an equivalent of std::pair<bool, std::string> as a function return type. In downstream code it would look better to use ok and msg instead of first and second accessors to avoid unnecessary API lookup. And I don't seem to be able to write it correctly using inheritance as std::pair may leak without virtual destructor. Wanted to avoid my own struct as the solution in Renamed std::pair members - to reuse existing Move constructor and other plumbing. Is it possible at all?

Edit:

After the feedback seems to be that the recommended way to go is:

struct res {
    bool ok;
    std::string msg;
};

res fnk() { ...; return r };

Do I understand correctly that C++11 compiler expected to generate the move constructor to avoid copying the string?

Community
  • 1
  • 1
Vlad Didenko
  • 4,481
  • 4
  • 25
  • 34
  • The compiler provides all the necessary plumbing for you. What you don't get for free is the relational operators and an `std::make_pair` equivalent. – juanchopanza Oct 18 '13 at 05:16
  • Are you saying that return of `r` in `struct res { bool ok; std::string msg }; res fnk() { ...; return r };` will automatically move value of `r` into the receiver when `fnk` returns? – Vlad Didenko Oct 18 '13 at 05:24
  • 2
    It depends on how you call the function, but the most likely scenario is that you get copy elision. But the compiler will generate a move copy constructor and a move copy assignment operator for you (unless you define your own constructors, in which case you can re-enable them using `default`. See [here](http://stackoverflow.com/questions/4943958/conditions-for-automatic-generation-of-default-ctor-copy-ctor-and-default-assi)). – juanchopanza Oct 18 '13 at 05:29
  • Thank you, this would address the need. Looks like it is not available in VC++2012 now and it will be available [after VC++2013](http://stackoverflow.com/questions/13344800) (next version after what I have). If I read [Herb Sutter](http://herbsutter.com/2013/09/09/visual-studio-2013-rc-is-now-available/) correctly it is going to be not earlier than in a 2014 VC++ update. – Vlad Didenko Oct 18 '13 at 05:49
  • 2
    I don't think the lack of virtual destructor would be a problem in this case... – CygnusX1 Oct 18 '13 at 05:50
  • @CygnusX1, should not, I do not add data. But then I am having a syntax issue - the only way I seem to do it is this `class res : std::pair { inline bool ok(){ return first; }; inline std::string msg() { return second; }; };`. Is there a way (or benefit) to "alias" `first` and `second` then? Greatly appreciate! – Vlad Didenko Oct 18 '13 at 06:59
  • 3
    You are changing the semantics: you return values, not references, and you cannot call the method on a const `res` instance, or via `const` reference or pointer. As to the benefit, I don't see what you gain compared to `struct res {bool ok; std::string msg;};`. – juanchopanza Oct 18 '13 at 07:07
  • Ah, makes sense, I'll use references. As far as benefit, my compiler (from VC++2012) does not seem to generate move constructors ( [see the previous comment](http://stackoverflow.com/questions/19441900/custom-accessor-names-in-a-specialised-pair?noredirect=1#comment28827202_19441900) ) so I thought to get by using inheritance. – Vlad Didenko Oct 18 '13 at 07:25
  • 1
    @VladDidenko In response to your edit: Yes, and the situation is even better: The compiler will hopefully create the return value in place! That means that even the (otherwise very cheap) move is avoided as well. – Ali Oct 18 '13 at 18:38

1 Answers1

1

Wanted to avoid my own struct as the solution in Renamed std::pair members - to reuse existing Move constructor and other plumbing.

I believe this the source of the misunderstanding: If you write your own struct, the compiler will generate the move constructor and "other plumbing" for you and for free.

And any decent compiler should be able to do copy elision, that is, construct the result in place; no copy, no move.

Using named inline accessors is also an option, especially if you really need to use std::pair; it is also detailed in the Renamed std::pair members question and in one of the answers.

Doing inheritance in this case would be a mistake in my opinion; I wouldn't do that. I don't see any benefit in it but I do see problems with it.

Community
  • 1
  • 1
Ali
  • 56,466
  • 29
  • 168
  • 265