标签: constexpr

声明constexpr initializer_list对象是否合法?

作为在讨论这个SO问题时提出的一个问题:

申报对象是否合法,可能是N3471constexpr std::initializer_list?例:

constexpr std::initializer_list<int> my_list{};
Run Code Online (Sandbox Code Playgroud)

为什么我认为它可能不合法:initializer_list必须是字面类型; 但有没有保证它是文字类型?

来自N3485的引文.

[dcl.constexpr]/9:

对象声明中使用的constexpr说明符将对象声明为const.这样的对象应具有文字类型并应初始化.

文字类型要求,[basic.types]/10,子项目类类型:

  • 具有以下所有属性的类类型(第9节):
    • 它有一个简单的析构函数,
    • 非静态数据成员(如果有)的brace-or-equal-initializers中的每个构造函数调用和完全表达式都是一个常量表达式(5.19),
    • 它是一个聚合类型(8.5.1)或者至少有一个constexpr构造函数或构造函数模板,它不是复制或移动构造函数,并且
    • 它的所有非静态数据成员和基类都是非易失性文字类型.

奖励积分;)用于回答if

constexpr std::initializer_list<int> my_list = {1,2,3,4,5};
Run Code Online (Sandbox Code Playgroud)

是合法的(有参考).虽然我认为上述+ [dcl.init.list]/5涵盖了这一点

c++ initializer-list language-lawyer constexpr c++11

20
推荐指数
1
解决办法
6173
查看次数

为什么在类中初始化的非整数静态数据成员必须是constexpr?

在类定义中初始化静态整型数据成员可以声明constconstexpr,但在类定义中初始化非整数的静态数据成员必须是constexpr:

class MyClass {
  static const     int   w = 5;          // okay
  static constexpr int   x = 5;          // okay
  static const     float y = 1.5;        // error!
  static constexpr float z = 1.5;        // okay
};
Run Code Online (Sandbox Code Playgroud)

有人知道为什么不允许y的声明吗?标准中将其定为非法的部分是9.4.2/3,但为什么它是非法的?

c++ static-members constexpr c++11

20
推荐指数
1
解决办法
6658
查看次数

Modern C++:初始化constexpr表

假设我有一个类X,哪个功能需要很多常量表值,比如一个数组A[1024].我有一个f计算其值的重复函数,就像

A[x] = f(A[x - 1]);
Run Code Online (Sandbox Code Playgroud)

假设这A[0]是一个已知常量,因此数组的其余部分也是常量.使用现代C++的功能预先计算这些值的最佳方法是什么,并且没有使用此数组的硬编码值存储文件?我的解决方法是一个const静态虚拟变量:

const bool X::dummy = X::SetupTables();

bool X::SetupTables() {
    A[0] = 1;
    for (size_t i = 1; i <= A.size(); ++i)
        A[i] = f(A[i - 1]);
}
Run Code Online (Sandbox Code Playgroud)

但我相信,这不是最美好的方式.注意:我强调数组相当大,我想避免代码的怪异.

c++ precompile constexpr c++11 c++17

20
推荐指数
2
解决办法
2467
查看次数

返回语句中的C++ constexpr函数

为什么constexpr函数在编译时没有被评估,而是在main函数的return语句中运行时?

它试过了

template<int x>
constexpr int fac() {
    return fac<x - 1>() * x; 
} 

template<>
constexpr int fac<1>() {
    return 1; 
} 

int main() {
    const int x = fac<3>();
    return x;
} 
Run Code Online (Sandbox Code Playgroud)

结果是

main:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 6
        mov     eax, 6
        pop     rbp
        ret
Run Code Online (Sandbox Code Playgroud)

与gcc 8.2.但是当我在return语句中调用该函数时

template<int x>
constexpr int fac() {
    return fac<x - 1>() * x; 
} 

template<>
constexpr int fac<1>() {
    return 1; 
} 

int main() {
    return fac<3>(); …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang constexpr

20
推荐指数
2
解决办法
1549
查看次数

如何将给定类型的所有元组元素提取到新元组中

现有元组重载std::get仅限于按索引或类型返回 1 个元素。想象一下,有一个包含多个相同类型元素的元组,并且您希望将它们全部提取到一个新元组中。

std::get<T>如何实现像这样返回给std::tuple定类型的所有出现的版本?

template<typename... Ts_out>
constexpr std::tuple<Ts_out...> extract_from_tuple(auto& tuple) {
    // fails in case of multiple occurences of a type in tuple
    return std::tuple<Ts_out...> {std::get<Ts_out>(tuple)...};
}

auto tuple = std::make_tuple(1, 2, 3, 'a', 'b', 'c', 1.2, 2.3, 4.5f);
auto extract = extract_from_tuple <float, double>(tuple);
// expecting extract == std::tuple<float, double, double>{4.5f, 1.2, 2.3}
Run Code Online (Sandbox Code Playgroud)

不确定按std::make_index_sequence元素访问每个元素是否可行。std::get<index>std::is_same_v

c++ tuples constexpr c++20

20
推荐指数
4
解决办法
3302
查看次数

constexpr与纯函数之间的关系

我是对的,那个:

  • 定义的任何函数constexpr都是纯函数,和
  • constexpr如果编译器的价格不是很高,那么任何纯函数都可以并且必须定义.

如果是这样,为什么不<cmath>定义函数constexpr

c++ constexpr c++11

19
推荐指数
3
解决办法
2598
查看次数

constexpr是编译器的"提示"(如内联)还是"绑定请求"?

constexpr编译器的指标还是强制执行行为?

手头的例子如下:

template<typename T> 
std::size_t constexpr getID() { return typeid(T).hash_code(); }
Run Code Online (Sandbox Code Playgroud)

hash_code是一个运行时常量,但即使请求编译时评估,此片段也会编译constexpr.只有在期望编译时常量的返回值之后,才会注意到这不能用作constexpr函数.

那么是constexpr一个"提示"(很像inline关键字)或编译器的"绑定请求"?

c++ constexpr c++11

19
推荐指数
2
解决办法
1026
查看次数

constexpr头文件中的全局常量和odr

不幸的是,我有点困惑constexpr,在头文件中声明的全局常量和odr.

简而言之:我们可以从这里结束

https://isocpp.org/files/papers/n4147.pdf

constexpr MyClass const MyClassObj () { return MyClass {}; }
constexpr char const * Hello () { return "Hello"; }
Run Code Online (Sandbox Code Playgroud)

比...好

constexpr MyClass const kMyClassObj = MyClass {};
constexpr char const * kHello = "Hello";
Run Code Online (Sandbox Code Playgroud)

如果我想"只使用"那些全局声明/定义的实体并且不想考虑我如何使用它们,那么在头文件中定义全局变量?

c++ linkage language-lawyer constexpr c++11

19
推荐指数
1
解决办法
7252
查看次数

如何检测是否有一个函数.是一个constexpr?并标记其他功能.constexpr取决于它?

假设我有一些功能模板f1:

template<typename f2>
int f1(int i, int j) noexcept {
  return i + j + f2(i, j);
}
Run Code Online (Sandbox Code Playgroud)

有没有办法确定是否f2(i, j)可以constexpr.(无论它是函数还是函子),所以也标记f1<f2>constexpr

我想在这里使用SFINAE一些如何,但没有找到如何检测constexpr使用类型特征

c++ constexpr c++11 c++14

19
推荐指数
2
解决办法
999
查看次数

constexpr函数,具有局部变量的延迟初始化

我正在尝试编写一个constexpr表单的函数:

constexpr int foo(bool cond) {
    int a, b, c;
    if (cond) {
        a = 1;
        b = 2;
        c = 3;
    }
    else {
        a = -1;
        b = -2;
        c = -3;
    }

    return a + b + c;
}
Run Code Online (Sandbox Code Playgroud)

但是,编译器抱怨我使用了未初始化的变量,尽管事实上保证了局部变量的最终初始化.

我可以重新编写函数来使用三元运算符,即int a = cond ? 1 : -1;等等,但我不愿意.有没有办法说服编译器初始化局部变量?

c++ constexpr

19
推荐指数
2
解决办法
1883
查看次数