“使用ODR”是什么意思?


92

这只是在另一个问题的背景下出现的。

显然,仅在使用ODR时才实例化类模板中的成员函数。有人可以解释这到底意味着什么。在上一个定义规则(ODR),维基百科的文章并没有提及“ ODR使用”。

但是该标准将其定义为

除非其对象满足在常量表达式中出现的要求(5.19)并且立即应用左值到右值转换(4.1),否则将使用其名称显示为可能评估的表达式的变量。

在[basic.def.odr]中。

编辑:显然这是错误的部分,整个段落包含针对不同事物的多个定义。这可能与类模板成员函数有关:

如果非重载函数的名称显示为可能评估的表达式或一组候选函数的成员,则如果非重载函数是纯虚函数,则如果通过重载解析从潜在评估的表达式中进行引用而选择了非重载函数,则该名称不会被使用函数及其名称未明确限定。

但是我不明白,该规则如何在多个编译单元中起作用?如果显式实例化类模板,是否会实例化所有成员函数?


2
请注意,[basic.def.odr] / 6适用于类模板的成员函数“可以有多个定义[...]”
dyp

3
“如果我显式实例化一个类模板,是否实例化了所有成员函数?” 是的,请参阅[temp.explicit] / 8 + 9
dyp

Answers:


71

它只是一个任意定义,标准使用它来指定何时必须为实体提供定义(而不只是声明)。该标准不只是说“已使用”,因为它可以根据上下文进行不同的解释。而且,某些ODR的使用并不真正与通常与“使用”相关联的使用相对应。例如,虚拟函数始终是ODR使用的,除非它是纯函数,即使它实际上并未在程序中的任何地方被调用。

完整的定义在§3.2第二段中,尽管其中包含对其他部分的引用以完成定义。

关于模板,使用ODR只是问题的一部分;另一部分是实例化。尤其是,第14.7节介绍了实例化模板的时间。但这两者是相关的:尽管第14.7.1节(隐式实例化)中的文本相当长,但基本原理是仅在使用模板时才实例化模板,在这种情况下,used表示使用了ODR。因此,类模板的成员函数只有在被调用时才被实例化,或者如果它是虚拟的并且类本身被实例化则将被实例化。该标准本身在很多地方都依赖于此:各个元素的std::list<>::sort用法<,但是您可以实例化不支持的元素类型的列表<,只要您不对其进行调用即可sort


ODR的使用是否可以与“物化的临时人员”重叠?
v.oddou

23

用简单的话来说,odr-used是指某种东西(变量或函数)用于必须存在其定义的上下文中。

例如,

struct F {
   static const int g_x = 2;
};

int g_x_plus_1 = F::g_x + 1; // in this context, only the value of g_x is needed.
                             // so it's OK without the definition of g_x

vector<int>  vi;
vi.push_back( F::g_x );      // Error, this is odr-used, push_back(const int & t) expect
                             // a const lvalue, so it's definition must be present

请注意,以上push_back是在MSVC 2013中传递的,此行为不符合标准,gcc 4.8.2和clang 3.8.0均失败,错误消息是:未定义对`K :: g_x'的引用


是否可以像vi.push_back( F::g_x );在c ++中那样使用odr使用静态数据成员?
Rankaba

但是还可以将rvalue传递给const int&吗?是否可以将静态const成员视为rvalue?
scottxiao '18年

8
简洁的开头句子+1:“用简单的词来说,odr-used表示必须在其中定义的上下文中使用某些东西(变量或函数)。”
Paul Masri-Stone

1
我不明白您如何编译该代码。他们在同一个TU吗?如果是,则F :: g_x已经在之前定义了push_back,当然它将通过。是不是
刘易斯·陈

1
@bigxiao“还可以传递右值”是,编译器将创建一个临时对象,并将引用绑定到该对象。OTOH在传递左值时意味着传递由左值的评估所引用的对象:当传递左值时,可以期望函数中的参数引用正确的对象。编译器不会创建临时文件。如果您想要一个临时工,请用制作一个operator+
curiousguy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.