简体   繁体   中英

Using auto as return type and return value nullptr in some cases

If we have method with return type auto , but into the method we will return a new object or nullptr . If I correctly understand when we return nullptr , it will create also new object through constructor.

Method is With .

Question is next: Which type will be used in place of auto ? It will depend on type returning by maybe or not: maybe is a function which returns Maybe<T> . When we call first With returning type is Maybe< Adress > ; second step it may be Maybe< Adress > since is the type of object or Maybe< std::string > - it returns if context is not nullptr .

struct Address {
    string* house_name = nullptr;
};

struct Person {
    Address* address = nullptr;
};

template <typename T> struct Maybe;

template <typename T> Maybe<T> maybe(T* context)
{
   return Maybe<T>(context);
}

template <typename T>
struct Maybe {
    T* context;

    Maybe(T *context) : context(context) { }

    template <typename TFunc>
    auto With(TFunc evaluator)
    { 
        return context != nullptr ? maybe(evaluator(context)) : nullptr;
    }
 };

 ...

 void print_house_name(Person* p)
 {
    auto z = maybe(p)
    .With([](auto x) { return x->address; })
    .With([](auto x) { return x->house_name; })
    .Do([](auto x) { cout << *x << endl; });
 }


int main()
{
   //print_house_name(nullptr);

   Person p;

   print_house_name(&p); // nothing

}

Which type will be used in place of auto ?

The return type of your function is determined by the type of the expression in the single return statement. In your case the statement is:

return context != nullptr ? maybe(evaluator(context)) : nullptr;

The returned expression is a ternary operator whose two potential values have different types ( Maybe<C> , for some class C not necessarily T , and nullptr_t ). This is only well-formed if one of the types is implicitly convertible to the other. Normally nullptr_t converts only to/from other pointer types, so let's look at the implicit conversions defined for Maybe (there's only one):

Maybe(T *context) : context(context) { }

A pointer type can be converted to a Maybe . So nullptr gets converted to C* which then gets converted to a Maybe<C> object (whose context is null). Again, I'm using C instead of T because this type need not be the same template parameter that is part of the type of *this . The returned type is the same regardless of the value of context .

If you want to see this implicit conversion break, make the conversion to Maybe explicit, as in explicit Maybe(T *context) : context(context) { } .

auto isn't magical. It it simply a placeholder that your compiler fills in with a concrete, deduced type. The end result is exactly the same as if you had written the deduced type manually.

"If I correctly understand when we return nullptr, it will create also new object through constructor". No. Returning nullptr does not call any constructors. It simply returns a null value of the appropriate type. No object is constructed.

"Which type will be instead auto" - The return tupe will be whatever the type of what you actually return is . And that can only ever be one specific type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM