标签: constexpr

与定义的类相同类型的静态constexpr成员

我希望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++ constexpr c++11

38
推荐指数
3
解决办法
4770
查看次数

为什么分解声明不能成为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?(除了"因为标准这么说").

c++ constexpr c++17 structured-bindings

38
推荐指数
1
解决办法
3649
查看次数

常数整数和常数求值

考虑以下程序:

#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++ constexpr c++20

38
推荐指数
1
解决办法
629
查看次数

在C++中修改constexpr函数中的全局变量17

在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++ language-lawyer constexpr c++17

36
推荐指数
1
解决办法
1512
查看次数

用SFINAE检测constexpr

我正在努力升级一些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之后可用,则第一个函数通过重载分辨率来选择. …

c++ templates sfinae constexpr c++11

35
推荐指数
1
解决办法
3983
查看次数

在构造函数上指定constexpr会自动使从它创建的所有对象都是constexpr吗?

这是我的代码:

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已经在构造函数上使用的原因?如果是这种情况,那么假设 …

c++ language-lawyer constexpr c++11

35
推荐指数
3
解决办法
2万
查看次数

constexpr 上下文中带有 consteval 构造函数的新表达式

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)

c++ language-lawyer constexpr c++20 consteval

35
推荐指数
1
解决办法
1244
查看次数

std :: max()和std :: min()不是constexpr

我刚刚注意到新标准的定义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++ max min constexpr c++11

34
推荐指数
2
解决办法
1万
查看次数

constexpr 浮点数学有何含义?

从 C++11 开始,我们可以在编译时进行浮点数学运算。C++23 和 C++26 添加了constexpr一些函数,但不是全部。

constexpr一般来说,浮点数学很奇怪,因为结果并不完全准确。然而,constexpr代码应该始终提供一致的结果。C++ 如何解决这个问题?

问题

  • constexpr浮点数学 是如何工作的?
    • 所有编译器的结果都相同吗?
    • 对于同一编译器,编译时和运行时的结果是否相同?
  • 为什么有些功能有效constexpr,而其他功能则不然(例如std::nearbyint

c++ floating-point constexpr c++23 c++26

34
推荐指数
2
解决办法
2532
查看次数

constexpr是否暗示noexcept?

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)

c++ inline noexcept constexpr c++14

33
推荐指数
2
解决办法
3006
查看次数