繁体   English   中英

C ++ 11 / C ++中的文字类型14

[英]Literal Type Class in C++11/C++14

int x = 1; // Not Constant

class A {
    public:
        int value  = x;
        int value2 { x };
        A( int a )        : value( x ), value2( x ) {}
        A( int a, int b ) : value{ x }, value2{ x } {}
        constexpr A() : value{ 0 }, value2{ 0 } {}
};

constexpr int function( A obj1, A obj2, A obj3, A obj4, A obj5, A obj6, A obj7 ){ 
    return 1; 
}

int main(){

    int y = 2; // Not Constant
    A obj1   ( y );
    A obj2   { y };
    A obj3 =   y  ;
    A obj4 = { y };
    A obj5   ( y, y );
    A obj6   { y, y );
    A obj7 = { y, y };
    int var = function( obj1, obj2, obj3, obj4, obj5, obj6, obj7 );

    return 0;
}

C ++ 11标准(ISO / IEC 14882:2011),第3.9节,第10段陈述(强调我的):

类型是文字类型,如果它是:

  • 标量类型; 要么
  • 参考类型; 要么
  • 具有以下所有属性的类类型(第9节):
    • 它有一个简单的析构函数,
    • 非静态数据成员(如果有)的brace-or-equal-initializers中的每个构造函数调用和完全表达式都是一个常量表达式(5.19),
    • 它是一个聚合类型(8.5.1)或者至少有一个constexpr构造函数或构造函数模板,它不是复制或移动构造函数,并且
    • 它包含所有非静态数据成员和文字类型的基类; 要么
  • 一个文字类型的数组。

在我看来,考虑到粗体的子弹, class A类在C ++ 11中不是文字类型,因为对于不是常量表达式的非静态数据成员,存在构造函数调用和大括号或大小调整。 我尝试在构造函数定义之前放置constexpr ,并将构造函数调用分配给constexpr变量,以检查编译器是否抱怨,因为它们不是常量表达式。 但是,Clang和GCC都成功编译了它。 所以我可能错了。

  • 有谁知道为什么class A是文字类型?

在C ++ 14( N3652 )中删除了粗体的子弹,因此我理解class A是C ++ 14中的文字类型。 我需要知道因为functionconstexpr ,因此它的each of its parameter types shall be a literal type (C ++ 11 / C ++ 14 Standard,Section 7.1.15,Paragraph 3)。

编辑:在原始帖子中我使用了一个简单的例子,使其更容易阅读,并解释我已经尝试了很多组合。 现在我用其中一些组合更新了示例,以显示我尝试了不同的构造函数调用,定义和非静态数据成员初始化。 谢谢。

有谁知道为什么A类是文字类型?

它不是在C ++ 11中,而是在C ++ 14中,因为你在帖子中引用的原因。 然而...

但是,Clang和GCC都成功编译了它。 所以我可能错了。

你没错。 clang和gcc都没有。 尽管A不是文字类型,但代码确实是格式良好的......仅仅因为没有什么要求它是文字类型。 function可以是constexpr函数,但不会被调用为常量表达式。 var不是constexpr对象,因此没有强制要求所有对象都是文字类型。 你试过了吗:

constexpr int var = function(...);

那么代码就会形成错误,因为在这种情况下, function(...)需要是一个核心常量表达式,这需要文字类型,这是C ++ 11 A失败的要求。 (实际上,你在C ++ 14中也遇到了A s都不是constexpr对象的问题)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM