正如图块所暗示的,在C ++中,由于容器内部的对象必须是可分配的,因此不能包含用于保存引用的引用。引用初始化后,我们无法重新分配它。
但是,在我的程序中,我有一个static const std::map
,它将const引用保存为值,并且可以很好地编译。我想知道是不是因为映射被声明为const并在声明时初始化,所以告诉编译器“此对象是const,其内容不会更改,因此可以将const引用作为其值保留”。
我在其他任何地方都找不到答案。该代码有效,但我不想让其他开发人员感到困惑。
编辑, 抱歉,我没有包含代码。在这里:
const glm::dvec4& GetObjectColor(const msg::ObjectType type) {
static const std::map<msg::ObjectType, const glm::dvec4&> kObjectColorMap = {
{msg::ObjectType::PERSON, kWhite},
{msg::ObjectType::ANIMAL, kSilver},
{msg::ObjectType::SEDAN, kGray},
{msg::ObjectType::SUV, kRed},
{msg::ObjectType::VAN, kMaroon},
{msg::ObjectType::BICYCLE, kYellow},
{msg::ObjectType::TRICYCLE, kOlive},
{msg::ObjectType::MOTORCYCLE, kLime},
{msg::ObjectType::TRUCK, kGreen},
{msg::ObjectType::BUS, kAqua},
{msg::ObjectType::PICKUP, kTeal},
{msg::ObjectType::UNKNOWN, kBlue}};
return kObjectColorMap.at(type);
}
答案 0 :(得分:0)
不。你不能。
也许您已经看到了以下问题:Why does storing references (not pointers) in containers in C++ not work?
问题的前提是正确的。您不能将引用存储在容器中。
...并且可以正常编译。
不能引起编译器错误的代码不能安全地假定为正确。实际上,“编译没有错误”是您可以放到代码上的最低标准。请考虑以下可怕的代码:
int* dont_do_this_at_home;
*dont_do_this_at_home = 42; // serisouly: DONT DO THIS
我知道没有编译器会对此代码发出错误或警告,无论该代码无法再被破坏。此处可能发生的最好情况是您遇到了细分错误。最糟糕的是:恶魔从你的鼻子里飞出来。在此处阅读有关未定义行为的信息:https://en.cppreference.com/w/cpp/language/ub
如以上链接的问答中所述,语言规范说:您不能在容器中存储引用。如果仍然这样做,并且编译器不会产生错误,那么您不应假定您找到了解决规则的方法。
这类似于不允许在足球比赛中用手触摸球。您可以用手触摸球,但这并不违反规则。
考虑一下:
int a = 5;
std::map<int,int&> x{ { 1,a} }; // WRONG !!!
没有编译器错误,但仍然是错误的。 C ++不是足球,如果您违反规则,那么没有裁判会告诉您。
PS:有std::reference_wrapper
可以将引用存储在容器中。