constexpr和ODR [英] constexpr and ODR

查看:89
本文介绍了constexpr和ODR的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们有一个头文件widget.hpp,其内容如下:

If we have a header file widget.hpp with the contents below:

constexpr int foo = 10;

struct widget
{
    int bars[foo];
};

...并且我们有两个从两个仅包含widget.hpp的源文件生成的转换单元,这是否违反了一个定义规则(更具体地说,使用foo是否违反了一个定义规则)?

...and we have two translation units generated from two source files which both only include widget.hpp, does this violate the one definition rule (more specifically, does the use of foo violate the one definition rule)?

foo具有内部链接,但它也是一个常量表达式.从我在C ++ 11标准中对3.2.6的阅读中,我将在下面引用该内容,如果要求#2不仅仅涉及静态数据成员,则这是正确的格式.

foo has internal linkage but it is also a constant expression. From my reading of 3.2.6 in the C++11 standard, which I will quote below, this is well-formed if requirement #2 is not referring solely to static data members.

3.2.6要求#2:

3.2.6 requirement #2:

在D的每个定义中,

对应的名称,根据 3.4,应指代D定义内定义的实体,或应指代在重载解决方案(13.3)和 匹配部分模板专业化(14.8.3)后,除外 名称可以使用内部或内部引用非易失性const对象 如果对象在所有定义中都具有相同的文字类型,则没有链接 D,并使用常数表达式(5.19)初始化该对象, 并且该对象未使用过,并且该对象在中具有相同的值 D的所有定义

in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), except that a name can refer to a non-volatile const object with internal or no linkage if the object has the same literal type in all definitions of D, and the object is initialized with a constant expression (5.19), and the object is not odr-used, and the object has the same value in all definitions of D

推荐答案

我唯一可以看到有关您的案子的问题的地方是您对foo的使用是否符合odr-used的条件.至少可以弄清楚意图的最简单方法是引用n1337的相应部分(立即遵循官方标准,例如在这种情况下,大多数情况下是清除措辞的):

The only place I can see any room for question about your case would be whether or not your use of foo qualifies as odr-used or not. Perhaps the easiest way to clarify at least the intent would be to quote the corresponding section of n1337 (immediately followed the official standard, mostly cleaning up some phrasing, such as in this case):

[...]如果对象在D的所有定义中都具有相同的文字类型,并且该对象使用常量表达式(5.19)初始化,则名称可以引用具有内部链接或不具有链接的const对象.使用该对象的值(而不是地址),并且该对象在D的所有定义中都具有相同的值;

[...] a name can refer to a const object with internal or no linkage if the object has the same literal type in all definitions of D, and the object is initialized with a constant expression (5.19), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D;

您的使用显然符合所有这些要求.

Your use clearly meets all these requirements.

  1. foo在每种情况下的类型均为int.
  2. foo用常量表达式初始化.
  3. 您仅使用foo的值,而不使用地址.
  4. 在所有widget定义中,
  5. foo具有相同的值.
  1. foo has type int in every case.
  2. foo is initialized with a constant expression.
  3. you use only the value, not the address, of foo.
  4. foo has the same value in all defintions of widget.

也就是说,最好将foos更改为std::vector:

That said, you'd probably be better off changing foos to a std::vector instead:

struct widget { 
    std::vector<int> bars;

    widget : bars(foo) {}
};

这篇关于constexpr和ODR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆