我希望C类有一个类型为C的静态constexpr成员.这在C++ 11中是否可行?
尝试1:
struct Foo {
constexpr Foo() {}
static constexpr Foo f = Foo();
};
constexpr Foo Foo::f;
Run Code Online (Sandbox Code Playgroud)
g ++ 4.7.0说:'无效使用不完整类型'指的是Foo()调用.
尝试2:
struct Foo {
constexpr Foo() {}
static constexpr Foo f;
};
constexpr Foo Foo::f = Foo();
Run Code Online (Sandbox Code Playgroud)
现在的问题是在类定义中缺少constexpr成员的初始化器f.
尝试3:
struct Foo {
constexpr Foo() {}
static const Foo f;
};
constexpr Foo Foo::f = Foo();
Run Code Online (Sandbox Code Playgroud)
现在g ++抱怨重新声明Foo::f不同的内容constexpr.
考虑以下片段来测试即将发布的C++ 17特性分解声明(以前称为结构化绑定)
#include <cassert>
#include <utility>
constexpr auto divmod(int n, int d)
{
return std::make_pair(n / d, n % d); // in g++7, also just std::pair{n/d, n%d}
}
int main()
{
constexpr auto [q, r] = divmod(10, 3);
static_assert(q == 3 && r ==1);
}
Run Code Online (Sandbox Code Playgroud)
这在g ++ 7-SVN和clang-4.0-SVN上都失败了,并带有以下消息:
分解声明不能声明'constexpr'
删除constexpr定义并更改为assert()两个编译器上的常规工作.
关于此功能的WG21论文constexpr均未提及关键字,无论是正面还是负面.
问题:为什么不允许分解声明constexpr?(除了"因为标准这么说").
考虑以下程序:
#include <iostream>
#include <type_traits>
constexpr int f() {
if (std::is_constant_evaluated())
return -1;
else return 1;
}
int main() {
int const i = f();
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
它打印-1在运行时(wandbox)。
但是,如果我throw在编译时求值时使用该函数:
#include <iostream>
#include <type_traits>
constexpr int f() {
if (std::is_constant_evaluated())
throw -1; // <----------------------- Changed line
else return 1;
}
int main() {
int const i = f();
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
它可以编译并输出1(wandbox)。为什么我没有出现编译失败?
在C++ 17中,您是否可以修改constexpr函数中的全局变量?
#include <iostream>
int global = 0;
constexpr int Foo(bool arg) {
if (arg) {
return 1;
}
return global++;
}
int main() {
std::cout << global;
Foo(true);
std::cout << global;
Foo(false);
std::cout << global;
}
Run Code Online (Sandbox Code Playgroud)
我不希望你能够,但clang 6允许它:https://godbolt.org/g/UB8iK2
但是,海湾合作委员会不会:https://godbolt.org/g/ykAJMA
哪个编译器正确?
我正在努力升级一些C++代码以利用C++ 11中的新功能.我有一个特性类,其中有一些函数返回基本类型,这些函数大部分时间(但并不总是)返回一个常量表达式.我想根据功能是否做不同的事情constexpr.我提出了以下方法:
template<typename Trait>
struct test
{
template<int Value = Trait::f()>
static std::true_type do_call(int){ return std::true_type(); }
static std::false_type do_call(...){ return std::false_type(); }
static bool call(){ return do_call(0); }
};
struct trait
{
static int f(){ return 15; }
};
struct ctrait
{
static constexpr int f(){ return 20; }
};
int main()
{
std::cout << "regular: " << test<trait>::call() << std::endl;
std::cout << "constexpr: " << test<ctrait>::call() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
额外的int/ ...参数是这样的,如果两个函数在SFINAE之后可用,则第一个函数通过重载分辨率来选择. …
这是我的代码:
class test{
public:
constexpr test(){
}
constexpr int operator+(const test& rhs){
return 1;
}
};
int main(){
test t; //constexpr word isn't necessary
constexpr int b = t+test(); // works at compile time!
int w = 10; // ERROR constexpr required
constexpr int c = w + 2; // Requires w to be constexpr
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我注意到即使我没有指定测试,它仍然有效constexpr.我尝试通过执行相同的方式复制结果,int但我得到错误.具体来说,它希望我的int w内心constexpr int c = w + 2;成为constexpr.从我第一次尝试使用test,它是否工作,因为我constexpr已经在构造函数上使用的原因?如果是这种情况,那么假设 …
struct A {
consteval A() {};
};
constexpr bool g() {
auto a = new A;
delete a;
return true;
}
int main() {
static_assert(g());
}
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/jsq35WxKs
GCC 和 MSVC 拒绝该程序,ICC 和 Clang 接受它:
///MSVC:
<source>(6): error C7595: 'A::A': call to immediate function is not a constant expression
Compiler returned: 2
//GCC:
<source>: In function 'constexpr bool g()':
<source>:6:18: error: the value of '<anonymous>' is not usable in a constant expression
6 | auto a = new A;
| ^ …Run Code Online (Sandbox Code Playgroud) 我刚刚注意到新标准的定义min(a,b)和max(a,b) 不 定义constexpr.
例25.4.7,[alg.min.max]:
template<class T> const T& min(const T& a, const T& b);
template<class T> T min(initializer_list<T> t);
Run Code Online (Sandbox Code Playgroud)
这不是很可惜吗?我本来想写的
char data[ max(sizeof(A),sizeof(B)) ];
Run Code Online (Sandbox Code Playgroud)
代替
char data[ sizeof(A) > sizeof(B) ? sizeof(A) : sizeof(B) ];
char data[ MAX(sizeof(A),sizeof(B)) ]; // using a macro
Run Code Online (Sandbox Code Playgroud)
那些不可能的constexpr原因是什么?
从 C++11 开始,我们可以在编译时进行浮点数学运算。C++23 和 C++26 添加了constexpr一些函数,但不是全部。
constexpr一般来说,浮点数学很奇怪,因为结果并不完全准确。然而,constexpr代码应该始终提供一致的结果。C++ 如何解决这个问题?
constexpr浮点数学
是如何工作的?constexpr,而其他功能则不然(例如std::nearbyint)constexpr说明noexcept符是否意味着函数的说明符?对类似问题的回答对说明者说"是" inline,但Eric Niebler的文章让我想知道对当前问题的可能答案.在我看来,答案取决于使用constexpr函数的上下文:是常量表达式上下文还是运行时上下文,即在编译时是否已知函数的所有参数.
我希望答案是"是",但简单的检查表明情况并非如此.
constexpr
bool f(int) noexcept
{
return true;
}
constexpr
bool g(int)
{
return true;
}
static_assert(noexcept(f(1)));
static_assert(noexcept(g(2))); // comment this line to check runtime behaviour
#include <cassert>
#include <cstdlib>
int
main(int argc, char * [])
{
assert(noexcept(f(argc)));
assert(noexcept(g(argc)));
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)