C++ 声明一个引用并稍后初始化?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14882995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:46:36  来源:igfitidea点击:

Declare a reference and initialize later?

c++reference

提问by user1861088

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

我有对 的引用MyOjbect,但确切的对象取决于条件。所以我想做这样的事情:

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

I cannot do this right now because the compiler does not allow me to declare but not initialize a reference. What can I do to achieve my goal here?

我现在不能这样做,因为编译器不允许我声明但不初始化引用。我可以做些什么来实现我的目标?

采纳答案by Zaffy

You need to initliaze it. But if you would like to conditionally initialize it, you can do something like this:

你需要初始化它。但是如果你想有条件地初始化它,你可以这样做:

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

回答by Jonathan Wakely

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 constreference, which can bind to a temporary, if the object must be non-const, then again stop trying to use a reference:

请注意,这两个版本都使用const引用,它可以绑定到临时对象,如果对象必须是非常量,则再次停止尝试使用引用:

MyObject obj = createObject([condition]);

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

由于返回值优化,这可能与您尝试做的一样有效

回答by 0x499602D2

AFAIK this can't be done with a reference. You'd have to use a pointer:

AFAIK 这不能通过参考来完成。你必须使用一个指针:

MyClass *ptr;

if (condition)
    ptr = &object;
else
    ptr = &other_object;

The pointer will act similar to a reference. Just don't forget to use ->for member access.

指针的作用类似于引用。只是不要忘记->用于成员访问。

回答by suszterpatt

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.

当然,关于参考文献的通常免责声明也适用。

回答by suszterpatt

In C++, you can't declare a reference without initialization. You must initialize it.

在 C++ 中,您不能在没有初始化的情况下声明引用。您必须对其进行初始化。

回答by Latawiec

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

我喜欢做的是立即执行的 lambda。

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.

假设我们想要一个const std::string&从地图下的变量 - 如果地图不包含给定的键 - 我们想要抛出。

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)

您还可以使用std::invoke()使其更具可读性(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.
    }
  });
}

回答by Anonymous

MyClass *ptr;

if (condition)
    ptr = &object;
else
    ptr = &other_object;

MyClass &ref = *ptr;

回答by VIPK

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

if([条件]) MyObject& ref = MyObject([something]); else MyObject& ref= MyObject([别的东西]);

回答by fk0

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.

您可以使用“extern”关键字:第一次(假设,在头文件中)您可以使用“extern”关键字在声明之前声明变量。稍后(在源文件中)您重复没有“extern”的声明并为其赋值。