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

J L*_*J L 9 c++ types literals 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;
}
Run Code Online (Sandbox Code Playgroud)

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标准,第7.1.15,第3段).

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

Bar*_*rry 5

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

它不在 C++11 中,但在 C++14 中,原因如您在帖子中引用的那样。然而...

然而,Clang 和 GCC 都编译成功。所以我可能是错的。

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

constexpr int var = function(...);
Run Code Online (Sandbox Code Playgroud)

那么代码将是格式错误的,就像在本例中一样,function(...)需要是一个核心常量表达式,它需要文字类型,而这一要求在 C++11 中A失败了。(实际上,在 C++14 中你也会遇到问题,所有As 都不是constexpr对象)。