这是 C++20 标准 (ISO/IEC 14882:2020) 第 13.5.4 节 ( [temp.constr.normal] ) 第 1 段中的示例(重点是我的):
\n\n\n概念 ID C<A1 , A2 , ..., An> 的范式是用A1 , A2 , ..., An 替换 C\xe2\x80\ 后 C 的约束表达式的范式每个原子约束中的参数映射中的 x99 各自的模板参数。如果任何此类替换导致无效类型或表达式,则该程序格式错误;无需诊断。
\n
template<typename T> concept A = T::value || true;\ntemplate<typename U> concept B = A<U*>;\ntemplate<typename V> concept C = B<V&>;\nRun Code Online (Sandbox Code Playgroud)\n\nB\xe2\x80\x99s 约束表达式的规范化是有效的,并且会导致
T::value(具有映射T -> U*) Vtrue(具有空映射),尽管该表达式T::value对于指针类型来说格式不正确 …
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(){ …Run Code Online (Sandbox Code Playgroud) class A {
public:
int num;
A ( int param ) : num( param ) {}
operator decltype( auto )( ){ return num; }
};
class B {
public:
int num;
A objA;
B ( int param ) : num( param ), objA( param ) {}
//operator A( ) { return objA; } // Works // #1
//operator int( ) { return objA; } // Works // #2
//operator char( ) { return objA; } // Actually Not Needed // …Run Code Online (Sandbox Code Playgroud) 在C ++ 14标准(ISO / IEC 14882:2014)中,第5.19节第2款(强调我的)中添加了“ 不可更改 ”一词:
甲条件表达式 e是一个核心常量表达式除非e的评价,如下所述抽象机(1.9),将评估下面的表达式中的一个的规则:
- [...]
- 左值到右值转换(4.1),除非将其应用于
- [...]
- 非易失性glvalue,它引用用constexpr定义的非易失性对象,或引用该对象的不可更改子对象,或者
因此,此代码在C ++ 14中不正确:
class A {
public:
mutable int x;
};
int main(){
constexpr A a = {1};
constexpr int y = a.x;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,在C ++ 11中是否正确?
这是缺陷报告(CD3)1405,他们提议在其中添加非可变的:
当前,文字类类型可以具有可变成员。尚不清楚这是否会对constexpr对象和常量表达式造成任何特殊的问题,如果是这样,应该如何处理。
所以我会说这是正确的C ++ 11代码。尽管如此,我还是使用-std = c ++ 11尝试了Clang和GCC,并且都输出了一个错误,指出常量表达式中不允许使用可变变量。但是该约束是在C ++ 14中添加的,而在C ++ 11中则没有。
有谁知道该代码在C ++ 11中是否正确?
另请参阅缺陷报告(CD3)1428。
有这个结构:
struct A {
struct B {
int a = 21;
int b;
int c = 22;
int d;
int e = 23;
};
B b1 = { 11, 12 };
B b2 = { 11, 12, 13 };
int x;
};
Run Code Online (Sandbox Code Playgroud)
并声明:
A a = { { 1, 2, 3, 4 }, { 1 }, 5 };
Run Code Online (Sandbox Code Playgroud)
根据Clang(3.8.0)和GCC(5.4.0),这些是8种可能组合的值(a.b1.e和a.b2.a是重复的情况),关于初始值的位置从(或不),:
a.b1.a = 1 // 111
a.b1.b = 2 // 110
a.b1.c = 3 // 101
a.b1.d = 4 // 100
a.b2.b …Run Code Online (Sandbox Code Playgroud) #include <iostream>
using namespace std;
struct A {
// Some Other Code
int x;
};
A a1;
int main(){
A a2;
cout << "a1.x = " << a1.x << endl;
cout << "a2.x = " << a2.x << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
C++14 标准 (ISO/IEC 14882:2014) 第 8.5 节,第 12 段:
如果没有为对象指定初始化程序,则该对象是默认初始化的。当获得具有自动或动态存储期限的对象的存储时,该对象具有不确定值,如果没有对该对象执行初始化,则该对象保留一个不确定值,直到该值被替换(5.17)。[注意:具有静态或线程存储持续时间的对象是零初始化的,参见 3.6.2。- 尾注]
那么a1有静态存储持续时间和a2自动存储持续时间吗?的定义Struct A在全局命名空间以及a1声明中,而a2声明在块范围内(在main()函数内部)。
此外,第 3.6.2 节说:
第 1 段:
作为程序启动的结果,具有静态存储持续时间的非局部变量被初始化。
第 2 段: …
#include <iostream>
using namespace std;
constexpr int f(bool b){ return b ? throw 0 : 0; } // OK
constexpr int f() { return f(true); } // Ill-Formed, No Diagnostic Required
int main(){
try{
f();
}catch( int x ){
cout << "x = " << x << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该代码是C ++ 14标准(ISO / IEC 14882:2014)第7.1.5节第5段的示例:
对于非模板,非默认constexpr函数或非模板,非默认,非继承constexpr构造函数,如果不存在参数值,则该函数或构造函数的调用可以是核心常量的评估子表达式表达式(5.19),程序格式错误;无需诊断。
它被描述为“ 格式错误,不需要诊断 ”,因为throw-expression不是核心常量表达式(5.19 / 2)。但是,Clang和GCC都可以成功编译它(Ideone)。
我还发现了有关标准措辞的这些有趣的讨论:
一个/该程序是否可能“ 格式错误,不需要诊断 ”,并且允许编译器成功编译该程序?
template<typename T> using unsized_raw_array = T[];
auto &&z = unsized_raw_array<int>{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
尝试相同,但没有双&符号(&&)会导致clang和gcc的不同行为:
template<typename T> using unsized_raw_array = T[];
auto z = unsized_raw_array<int>{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
我预计这是一个错误,因为它是一个rvalue(通用/转发/临时对象)引用,并且双&符号缺失(&&).这就是gcc 6.3.0所发生的事情:
error: taking address of temporary array但是,clang 3.9.1会成功编译并执行它,允许在下一个语句中打印数组的值.我只收到这个警告(在某些情况下我甚至没有得到警告):
warning: pointer is initialized by a temporary array, which will be destroyed at the end of the full-expression [-Waddress-of-array-temporary]哪个编译器正确?