Declare a reference and initialize later?

后端 未结 10 2102
遥遥无期
遥遥无期 2020-12-01 05:58

I have a reference to MyOjbect, but the the exact object depends on a condition. So I want to do something like this:

MyObject& ref; 
if([co         


        
相关标签:
10条回答
  • 2020-12-01 06:26

    You can't do this. References must be bound to something, you may not like it but it prevents a whole class of errors, because if you have a reference you can always assume it's bound to something, unlike a pointer which could be null.

    Your example code wouldn't work anyway because you attempt to bind a non-const reference to a temporary object, which is invalid.

    Why do you need it to be a reference anyway? One solution would be to ensure your type has an inexpensive default constructor and can be efficiently moved, then just do:

    MyObject obj; 
    if([condition]) 
      obj = MyObject([something]) 
    else 
      obj = MyObject([something else]);
    

    Otherwise you'd have to put the conditional code in one or more functions, either:

    const MyObject& ref = createObject([condition]);
    

    or

    const MyObject& ref = [condition] ? doSomething() : doSomethingElse();
    

    Note that both these versions use a const reference, which can bind to a temporary, if the object must be non-const, then again stop trying to use a reference:

    MyObject obj = createObject([condition]);
    

    This will probably be just as efficient as what you were trying to do, thanks to the return value optimization

    0 讨论(0)
  • 2020-12-01 06:31

    Short answer: you don't.

    Marginally longer answer: do something like this:

    MyObject& getObject()
    {
        if([condition]) 
            return [something] 
        else 
            return [something else];
    }
    
    MyObject& ref = getObject();
    

    Usual disclaimers regarding references apply of course.

    0 讨论(0)
  • 2020-12-01 06:33

    if([condition]) MyObject& ref = MyObject([something]); else MyObject& ref= MyObject([something else]);

    0 讨论(0)
  • 2020-12-01 06:40

    What I like to do is a lambda that's immediately executed.

    Let's suppose we want a const std::string& to a variable from under the map - if map does not contain given key - we want to throw.

    int main()
    {
      std::map<std::string, std::string> myMap = {{"key", "value"}};
    
      const std::string& strRef = [&]()->const std::string& {
        try {
          return myMap.at("key"); // map::at might throw out_of_range
        }
        catch (...) {
          // handle it somehow and/or rethrow.
        }
      }(); // <- here we immediately call just created lambda.
    }
    

    You could also use std::invoke() to make it more readable (since C++17)

    int main()
    {
      std::map<std::string, std::string> myMap = {{"key", "value"}};
    
      const std::string& strRef = std::invoke([&]()->const std::string& {
        try {
          return myMap.at("key"); // map::at might throw out_of_range
        }
        catch (...) {
          // handle it somehow and/or rethrow.
        }
      });
    }
    
    0 讨论(0)
  • 2020-12-01 06:42
    MyClass *ptr;
    
    if (condition)
        ptr = &object;
    else
        ptr = &other_object;
    
    MyClass &ref = *ptr;
    
    0 讨论(0)
  • 2020-12-01 06:42

    You can use "extern" keyword: first time (assume, in header file) you can declare your variable preceding declaration with "extern" keyword. Later (in source file) you repeat declaration without "extern" and assign value to it.

    0 讨论(0)
提交回复
热议问题