关于 ODR 有很多问题,但我找不到我要找的东西,所以如果这是重复的或标题不合适,我们深表歉意。
考虑以下:
struct t {t(*id)();};
template<typename T>
t type() {return {type<T>};}
这是对我为每种类型定义唯一标识符的尝试的过度简化,希望它在不同的编译单元中保持唯一。
特别是,给定一个具体的类型T
,std::string
假设两个不同的编译单元在头文件中包含上述代码,我想表达
type<T>().id
在两个单元中采用相同的值(类型t(*)()
),因此用作类型的唯一标识符T
。
该值是函数的地址type<T>
,所以问题是程序type<T>
中的唯一函数是否由单定义规则保证。iso 3.2/3 说
每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的准确定义。
3.2/2 在哪里
名称显示为潜在求值表达式或 [...] 的非重载函数是 odr 使用的,除非 [...]
如果一个函数的地址被占用,我假设它是非内联的(尽管我在标准中找不到它)。
iso 3.2/5 列出了一些例外,但对函数的唯一引用是
具有外部链接的内联函数、[...]、非静态函数模板、[...]、类模板的成员函数或未指定某些模板参数的模板特化 [...]
而且这里似乎没有。
一个可验证的示例需要多个文件。事实上,Dieter Lücking给出了一个声称失败的例子,尽管在我的情况下它并没有失败(我不认为这是任何形式的“保证”)。
那么,这会奏效吗?