I agree. I think returning tuple flows better and seems to be the way the
language is progressing.

Also, I think it's probably even more efficient than using out variable.
Using out variable we'd pay the cost of the default constructor and then
the cost populating any state which is essentially equivalent to a copy
constructor.  While returning tuples we can let the compiler perform RVO
and the standard library perform small object optimization.

The other question though is, could function overload resolution be a valid
use case for out variables (particularly in PdxReader, for example)?

Thanks,
David

On Mon, Oct 2, 2017 at 10:56 AM, Jacob Barrett <jbarr...@pivotal.io> wrote:

> Basic docs on the C++11 tuple use for multiple return types:
> http://en.cppreference.com/w/cpp/utility/tuple
>
> In C++11 we would have:
>
> std::tuple<int, std::string> foo::getAAndB() {...}
>
> And call it with:
>
> int a;
> std::string b;
> std::tie(a, b) = foo.getAAndB();
>
> While this isn't super pretty I would argue it is more readable than.
>
> std::string b;
> auto a = foo.getAAndB(b);
>
> I believe this is unclear when reading that b is an out variable rather
> than passing empty string value to the function.
>
> And certainly easier to understand than:
> int a;
> std::string b;
> foo.getAAndB(a, b);
>
> Again, is a and be inadvertently uninitialized?
>
> Alternatively the tuple can be called like:
>
> auto r = foo.getAAndB();
> auto a = std::get<0>(r);
> auto b = std::get<1>(r);
>
>
>
>
> Another interesting blog on the issue:
> https://dzone.com/articles/returning-multiple-values-from-functions-in-c
>
> -Jake
>
>
> On Mon, Oct 2, 2017 at 9:07 AM Jacob Barrett <jbarr...@pivotal.io> wrote:
>
> > We are already in contention with our style guide on many items. I
> suggest
> > we use it as a guideline only and establish our own rules. The more
> > research into the Google C++ guide is really driven by legacy C/C++
> issues
> > at Google.
> >
> > Regarding the in/out issue I am for multiple return types so that we
> > migrate to a more functional programming style. An interesting article I
> > read last week on this issue sheds some good light on why,
> > https://www.fluentcpp.com/2016/11/22/make-your-functions-functional/.
> >
> > As a bonus, once we go C++17 (in 2020ish I am sure) we can use auto
> > structured return values.
> > auto [a, b] = foo.getAAndB();
> >
> > -Jake
> >
> >
> > On Wed, Sep 27, 2017 at 1:14 PM David Kimura <dkim...@pivotal.io> wrote:
> >
> >> I forgot to mention, and it's probably worth noting, that passing
> >> non-const
> >> ref knowingly defies our style-guide.
> >>
> >> https://google.github.io/styleguide/cppguide.html#Reference_Arguments
> >>
> >> Thanks,
> >> David
> >>
> >> On Wed, Sep 27, 2017 at 12:32 PM, Ernest Burghardt <
> eburgha...@pivotal.io
> >> >
> >> wrote:
> >>
> >> > Currently we have a mix of the counter argument...
> >> >
> >> > we use return values and you have to call the explicitly named
> methods:
> >> > double* readDoubleArray(const char* fieldName, int32_t& length)
> >> > int64_t* readLongArray(const char* fieldName, int32_t& length)
> >> >
> >> > I'm good with non-const refs in-out to the specific method calls OR
> >> > overload readArray and different return values...
> >> >
> >> > EB
> >> >
> >> > On Wed, Sep 27, 2017 at 1:27 PM, Michael William Dodge <
> >> mdo...@pivotal.io>
> >> > wrote:
> >> >
> >> > > I like the idea of using non-const references for in-out parameters
> >> only
> >> > > and using tuples for the cases where there are multiple out
> >> parameters.
> >> > > Yes, the return type does not participate in overload resolution
> but I
> >> > > don't think there would be many cases where that would be an issue.
> >> (But
> >> > I
> >> > > haven't done any research so that's just a WAG.)
> >> > >
> >> > > Sarge
> >> > >
> >> > > > On 27 Sep, 2017, at 12:22, David Kimura <dkim...@pivotal.io>
> wrote:
> >> > > >
> >> > > > Is there a use case in our C++ client code to ever use out
> >> parameters?
> >> > > >
> >> > > > Currently code uses out parameters to return multiple values from
> a
> >> > > > function.  [1]
> >> > > >
> >> > > > virtual int64_t* PdxReader::readLongArray(const char* fieldName,
> >> > int32_t&
> >> > > > length) = 0;
> >> > > >
> >> > > >
> >> > > > In this case, we could return a tuple instead.  I think the
> >> advantage
> >> > of
> >> > > > this is it doesn't force a separation between the variable
> >> declaration
> >> > > and
> >> > > > assignment, which may lead to spaghetti code.  I think avoiding
> out
> >> > > > parameters also leads to more well defined behavior.  What would
> one
> >> > > expect
> >> > > > if they called getCqListeners with an already partially populated
> >> > vector?
> >> > > > [2]
> >> > > >
> >> > > > virtual void CqAttributes::getCqListeners(
> std::vector<CqListenerPtr&
> >> > v)
> >> > > = 0;
> >> > > >
> >> > > >
> >> > > > As a counter argument, could function overload resolution be a
> valid
> >> > use
> >> > > > case of out parameters?  In PdxReader::readType methods, Type
> seems
> >> > > > redundant.  As a user, why should I have to call
> >> > > readLongArray(int64_t[]&)
> >> > > > rather than just call read(int64_t[]&)?  In this case, if we
> didn't
> >> use
> >> > > out
> >> > > > parameter our signature clashes with other read methods.
> >> > > >
> >> > > > Thoughts?
> >> > > >
> >> > > > Thanks,
> >> > > > David
> >> > > >
> >> > > > [1]
> >> > > > https://github.com/apache/geode-native/blob/
> >> > > 44635ffa95926c9cffecc1dcaac02fb3012d1eef/cppcache/include/
> >> > > geode/PdxReader.hpp#L288
> >> > > > [2]
> >> > > > https://github.com/apache/geode-native/blob/
> >> > > 44635ffa95926c9cffecc1dcaac02fb3012d1eef/cppcache/include/
> >> > > geode/CqAttributes.hpp#L60
> >> > >
> >> > >
> >> >
> >>
> >
>

Reply via email to