使用枚举作为常量表达式。哪个编译器正确? [英] Using an enum as a constant expression. Which compiler is right?

查看:142
本文介绍了使用枚举作为常量表达式。哪个编译器正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码使用枚举成员 m 作为常量表达式,即作为模板参数。该代码在gcc下而不在clang下编译(实时演示)。叮当说:错误:非类型模板参数不是常量表达式。

The following code uses enum member m as a constant expression, i.e. as a template parameter. The code compiles under gcc but not under clang (live demo). Clang says "error: non-type template argument is not a constant expression".

可以通过交换行 // 1 通过 A< tst< p> :: m>一个。因此,我的问题不是如何解决此问题,而是哪种编译器是正确的。

The problem can be solved by exchanging line // 1 by A<tst<p>::m> a. Therefore, my question is not how to fix this issue but which compiler is right.

template<size_t n> struct A{};

template<size_t n>
struct tst
{   enum : size_t { m= n % 15 };

    template<size_t p>
    void
    call( tst<p> const &t2 ) {
        A<t2.m>  a; // 1
    }
};


推荐答案

根据标准,Clang有权拒绝

According to the Standard, Clang is right to reject the code.

t2.m 是类成员访问表达式。 [expr.ref] / 1说:

t2.m is a class member access expression. [expr.ref]/1 says:


[...]计算点或箭头之前的后缀表达式;该评估的
结果与 id-expression 一起,
决定整个后缀表达式的结果。

[...] The postfix expression before the dot or arrow is evaluated; the result of that evaluation, together with the id-expression, determines the result of the entire postfix expression.

还有一条注释:


如果评估了类成员访问表达式,则子表达式$ b即使没有必要使用结果来确定整个后缀表达式的
值,例如,如果
id-expression 表示静态成员,也会进行$ b评估。

If the class member access expression is evaluated, the subexpression evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.

因此,将评估子表达式 t2 。 [expr.const] /2.9表示 e 表达式不能为核心常量表达式,如果对其求值会导致对

So, the subexpression t2 is evaluated. [expr.const]/2.9 says that an expression e cannot be a core constant expression if evaluating it results in the evaluation of


一个 id-expression ,它引用引用
类型的变量或数据成员,除非引用具有前面的初始化,并且其中的任何一个

an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either


  • 使用常量表达式对其进行初始化,或者

  • 其生存期始于对的求值e ;

  • it is initialized with a constant expression or
  • its lifetime began within the evaluation of e;

t2 引用的引用类型变量不能满足要求,因此 t2.m 不是常量表达式,因为它不是核心常量表达式

t2 refers to a variable of reference type that doesn't satisfy the bullets, so t2.m is not a constant expression because it isn't a core constant expression.

所有引号均来自N4594,即当前发布的工作草案。自C ++ 11以来,文本略有变化,但是在这种情况下,含义是相同的。

All quotes from N4594, the current published working draft. The text has changed slightly since C++11, but the meaning in this case is the same.

这篇关于使用枚举作为常量表达式。哪个编译器正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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