我对C++很新,这是我的情况.我有一个参考MyOjbect,但确切的对象取决于条件.所以我想做这样的事情:
MyObject& ref;
if([condition])
ref = MyObject([something])
else
ref = MyObject([something else]);
Run Code Online (Sandbox Code Playgroud)
我现在不能这样做,因为编译器不允许我声明但不初始化引用.我能做些什么来实现我的目标?
Zaf*_*ffy 41
你需要初始化它.但是如果你想有条件地初始化它,你可以这样做:
MyObject& ref = (condition) ? MyObject([something]) : MyObject([something else]);
Run Code Online (Sandbox Code Playgroud)
0x4*_*2D2 15
AFAIK这不能用参考完成.你必须使用指针:
MyClass *ptr;
if (condition)
ptr = &object;
else
ptr = &other_object;
Run Code Online (Sandbox Code Playgroud)
指针的作用类似于引用.只是不要忘记使用->成员访问.
Jon*_*ely 14
你不能这样做.引用必须绑定到某些东西,你可能不喜欢它,但它可以防止整个类的错误,因为如果你有一个引用,你总是可以假设它绑定到某个东西,不像一个可能为null的指针.
您的示例代码无论如何都无法工作,因为您尝试将非const引用绑定到临时对象,这是无效的.
为什么你还需要它作为参考?一种解决方案是确保您的类型具有廉价的默认构造函数并且可以有效地移动,然后执行:
MyObject obj;
if([condition])
obj = MyObject([something])
else
obj = MyObject([something else]);
Run Code Online (Sandbox Code Playgroud)
否则,您必须将条件代码放在一个或多个函数中,或者:
const MyObject& ref = createObject([condition]);
Run Code Online (Sandbox Code Playgroud)
要么
const MyObject& ref = [condition] ? doSomething() : doSomethingElse();
Run Code Online (Sandbox Code Playgroud)
请注意,这两个版本都使用const引用,它可以绑定到临时,如果该对象必须是非const,则再次停止尝试使用引用:
MyObject obj = createObject([condition]);
Run Code Online (Sandbox Code Playgroud)
由于返回值优化,这可能与您尝试执行的操作一样高效
简短的回答:你没有.
更长的答案:做这样的事情:
MyObject& getObject()
{
if([condition])
return [something]
else
return [something else];
}
MyObject& ref = getObject();
Run Code Online (Sandbox Code Playgroud)
关于参考文献的通常免责声明当然适用.
小智 7
我想做的是一个立即执行的lambda。
假设我们想要一个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.
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用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.
}
});
}
Run Code Online (Sandbox Code Playgroud)
小智 5
MyClass *ptr;
if (condition)
ptr = &object;
else
ptr = &other_object;
MyClass &ref = *ptr;
Run Code Online (Sandbox Code Playgroud)