Clang接受以下代码,但gcc 拒绝它。
void h() { }
constexpr int f() {
return 1;
h();
}
int main() {
constexpr int i = f();
}
Run Code Online (Sandbox Code Playgroud)
这是错误消息:
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'constexpr int f()':
main.cpp:5:6: error: call to non-'constexpr' function 'void h()'
h();
~^~
main.cpp: In function 'int main()':
main.cpp:9:24: error: 'constexpr int f()' called in a constant expression
constexpr int i = f();
~^~
main.cpp:9:19: warning: unused variable 'i' [-Wunused-variable]
constexpr int i …
Run Code Online (Sandbox Code Playgroud) 下面突出显示的句子是什么意思?它与功能模板有关系吗?
并非所有函数声明都可以重载。此处指定不能过载的那些。如果程序在同一作用域中包含两个此类不可重载的声明,则该程序格式错误。[?注意:此限制适用于范围中的显式声明,以及此类声明与通过using-declaration([namespace.udecl])进行的声明之间的声明。它不适用于因名称查找(例如,由于使用指令)或重载解析(例如,用于操作员功能)而构造的功能集。-?尾注?]
c++ overloading using-directives language-lawyer name-lookup
本条款施加的限制可以避免哪些具体问题12.7p3
(见下段第一部分)?
在12.7p3
(见下文)所示的例子中,为什么X(this)
被认为是定义的?是因为X
不在路上E C D B A
吗?
struct A { };
struct B : virtual A { };
struct C : B { };
struct D : virtual A { D(A*); };
struct X { X(A*); };
struct E : C, D, X {
E() : D(this), // undefined: upcast from E* to A*
// might use path E* - D* - A*
// but D is not constructed
// D((C*)this), …
Run Code Online (Sandbox Code Playgroud)[basic.link] C++ 14标准中的第4段:
未命名的命名空间或在未命名的命名空间中直接或间接声明的命名空间具有内部链接.所有其他名称空间都有外部链接.如果名称为...,则具有未在上面给出内部链接的命名空间范围的名称与封闭命名空间具有相同的链接.
"上面间接声明另一个命名空间中的命名空间"是什么意思?
#include <iostream>
void f() { std::cout << "f()\n"; }
struct S {
typedef void(*p)();
operator p() { return f; }
};
int main()
{
S s;
s.operator p()();
}
Run Code Online (Sandbox Code Playgroud)
产量:
Run Code Online (Sandbox Code Playgroud)main.cpp:13:16: error: unknown type name 'p'; did you mean 'S::p'? s.operator p()(); ^ S::p main.cpp:6:19: note: 'S::p' declared here typedef void(*p)(); ^
但它应该,因为表达式s.operator p()()
访问对象的公共成员函数S::s
.我错过了什么吗?
如果我错了,我会很感激标准中引用的答案.
[class.dtor]/1包含以下语句:
每个DECL说明符的的DECL说明符-SEQ析构函数声明(如果有的话)的应是
friend
,inline
,或virtual
。
我真的很想看到一个使用带有friend
说明符的析构函数的例子。
我正在使用以下代码片段测试[expr.static.cast]/2(请参阅实例):
#include <iostream>
struct B{ int i = 2; };
struct D: public B{};
int main()
{
D d;
std::cout << &d << '\n';
std::cout << &(static_cast<D&>((B&)d)) << '\n';
std::cout << &(static_cast<const D&>((B&)d)) << '\n';
std::cout << &(static_cast<const volatile D&>((B&)d)) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
输出是:
0x7fff65a8f6d0
0x7fff65a8f6d0
0x7fff65a8f6d0
1
Run Code Online (Sandbox Code Playgroud)
在gcc中出现以下警告:
main.cpp: In function 'int main()':
main.cpp:13:57: warning: the address of 'd' will always evaluate as 'true' [-Waddress]
std::cout << &(static_cast<const volatile D&>((B&)d)) << '\n';
Run Code Online (Sandbox Code Playgroud)
为什么编译器将下面的最后一次转换强制为bool值?
后缀表达式后跟一个点.
或箭头->
,可选地后跟关键字template
(17.2),然后是id-expression,后缀表达式.评估点或箭头之前的后缀表达式; 67该评估的结果与id-expression一起确定整个后缀表达式的结果.
67)如果计算了类成员访问表达式,则即使不需要结果来确定整个后缀表达式的值,也会发生子表达式求值,例如,如果id-expression表示静态成员.
演示:
#include<iostream>
struct A { int i = 10; };
struct B : A { };
int main(){
std::cout << "decltype(&B::i) == int A::* ? " << std::boolalpha
<< std::is_same<decltype(&B::i), int A::*>::value << '\n'; //#1
A a;
std::cout << a.*(&A::i) << '\n';
std::cout << "decltype(&B::i) == int B::* ? "
<< std::is_same<decltype(&B::i), int B::*>::value << '\n'; //#2
B b;
std::cout << b.*(&B::i) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
代码打印
decltype(&B::i) == int A::* ? true
10
decltype(&B::i) == int B::* ? false …
Run Code Online (Sandbox Code Playgroud) c++ ×10
c++11 ×2
c++14 ×2
c++17 ×1
clang++ ×1
constexpr ×1
constructor ×1
destructor ×1
friend ×1
name-lookup ×1
overloading ×1
public ×1
standards ×1
static-cast ×1