这是在another question的背景下出现的。
显然,类模板中的成员函数只有在ODR使用时才会被实例化。有人能解释一下这到底是什么意思吗。wikipedia article on One Definition Rule (ODR)没有提到"ODR-use“。
然而,标准将其定义为
名称显示为潜在求值表达式的变量是odr使用的,除非它是满足在常量表达式(5.19)中出现的要求的对象,并且立即应用左值到右值的转换(4.1)。
在basic.def.odr中。
编辑:显然这是错误的部分,整个段落包含了对不同事物的多个定义。这可能是类模板成员函数的相关函数:
当从可能求值的表达式中引用时,如果通过重载解析选择了其名称显示为可能求值的表达式或候选函数集的成员的非重载函数,则除非该函数是纯虚函数且其名称未显式限定,否则将使用ODR.
然而,我不明白,这个规则是如何在多个编译单元中工作的?如果我显式实例化一个类模板,是否所有成员函数都实例化了?
发布于 2013-10-28 17:32:00
它只是一个任意的定义,标准使用它来指定何时必须为实体提供定义(而不仅仅是一个声明)。该标准没有说“已使用”,因为这可以根据上下文的不同而不同地解释。并且一些ODR使用并不真正对应于通常与“use”相关联的那些;例如,虚拟函数总是ODR使用的,除非它是纯函数,即使它实际上没有在程序中的任何地方被调用。
完整的定义在§3.2的第二段中,尽管这包含了对其他部分的引用来完成定义。
关于模板,ODR使用只是问题的一部分;另一部分是实例化。特别是,§14.7涵盖了模板实例化的时间。但两者是相关的:虽然§14.7.1 (隐式实例化)中的文本相当长,但基本原则是,只有在使用模板时才会实例化模板,在这种情况下,使用意味着ODR使用。因此,类模板的成员函数只有在它被调用时才会被实例化,或者如果它是虚的并且类本身是实例化的。标准本身在很多地方都依赖于此:std::list<>::sort
对单个元素使用<
,但只要不对其调用sort
,就可以在不支持<
的元素类型上实例化一个列表。
发布于 2017-08-08 08:58:20
简单地说,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是在MSVC2013中传递的,这种行为不符合标准,gcc 4.8.2和clang 3.8.0都失败了,错误消息是:引用F::g_x
未定义
https://stackoverflow.com/questions/19630570
复制相似问题