标签: constexpr

c ++ 11 constexpr将std :: array的列表展平为数组

我开始使用c ++ 11,constexpr和模板元编程似乎是一种在微型微控制器上保存稀缺内存的好方法.

有没有办法编写模板来展平constexpr数组列表,我需要的是一种方法:

constexpr std::array<int, 3> a1 = {1,2,3};
constexpr std::array<int, 2> a2 = {4,5};
constexpr auto a3 = make_flattened_array (a1,a2);
Run Code Online (Sandbox Code Playgroud)

我使用gcc 4.8.4(arm-none-eabi),如果需要,可以使用std = c ++ 11或c ++ 1y选项进行编译.

c++ arrays std constexpr c++11

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

我们可以在constexpr函数中省略const局部变量吗?

例如:

constexpr int g() { return 30; }    

constexpr int f()
{
    // Can we omit const?
    const int x = g();
    const int y = 10;

    return x + y;
}
Run Code Online (Sandbox Code Playgroud)

没有必要constexpr函数中声明局部变量const

局部变量的constexpr函数不等于没有const局部变量的函数吗?const

换句话说,constexpr函数是否强加(暗示)const它的局部变量?

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

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

constexpr const char*vs constexpr const char []

"第一次尝试"不会编译,而第二次尝试则不会编译.为什么?有什么不同?

第一次尝试:

#include <iostream>

int main()
{
    constexpr const char text2[] = "hello";
    constexpr const char * b = &text2[4];  // error: '& text2[4]' is not a constant expression
    std::cout << b << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

第二次尝试:

#include <iostream>
int main()
{
constexpr const char * text1 = "hello";
constexpr const char * a = &text1[4];
std::cout << a << std::endl;

return 0;
}
Run Code Online (Sandbox Code Playgroud)

我编译(g ++版本4.9.2)

g++ -std=c++11 -o main *.cpp
Run Code Online (Sandbox Code Playgroud)

这给出了以下错误

main.cpp: In function 'int main()':
main.cpp:7:40: error: '& text2[4]' …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

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

三路比较和constexpr函数模板:哪个编译器是对的?

考虑:

#include <compare>

template<class=void>
constexpr int f() { return 1; }

unsigned int x;
using T = decltype(x <=> f());
Run Code Online (Sandbox Code Playgroud)

GCC 和 MSVC 接受T. Clang 拒绝了它,并显示以下错误消息:

<source>:7:26: error: argument to 'operator<=>' cannot be narrowed from type 'int' to 'unsigned int'
using T = decltype(x <=> f());
                        ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

现场演示

如果模板头 ( template<class=void>) 被移除,或者如果f在 的声明之前显式或隐式实例化T,则 Clang 接受它。例如,Clang 接受:

#include <compare>

template<class=void>
constexpr int f() { return 1; }

unsigned x; …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer spaceship-operator constexpr c++20

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

当类型变量标记为 constexpr 时,编译器将类型变量类型从 uin16_t 更改为 int

我在尝试翻转号码的所有位时遇到了一个奇怪的问题。

#include <cstdint>

constexpr uint16_t DefaultValueForPortStatus { 0xFFFF };

void f(uint16_t x)
{

}

int main()
{
  f(~(DefaultValueForPortStatus));
}
Run Code Online (Sandbox Code Playgroud)

当我编译这个程序(GCC trunk)时,我收到一个错误:

警告:从“int”到“uint16_t”的无符号转换{aka“short unsigned int”}将值从“-65536”更改为“0”[-Woverflow]

当我从类型说明符中删除 constexpr 时,不会出现警告。这是为什么?为什么编译器将 uint16_t constexpr 变量更改为 int,而在非 constexpr 的情况下一切都很好?

c++ constexpr

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

constexpr C++ 错误:在定义之前使用了析构函数

我在使用 g++-12 时遇到错误,但在 clang++-13 中不会发生该错误。特别是,这段代码:

\n
struct A {\n    constexpr virtual ~A() = default;\n    constexpr A() = default;\n};\n\nstruct B : public A {\n    constexpr ~B() = default;\n    constexpr B() = default;\n};\n\nconstexpr int demo(){\n    B *b = new B();\n    delete b;\n    return 2;\n}\n\nint main(){\n    constexpr int demod = demo();\n    return demod;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

使用 clang++ 编译,但使用 g++ 编译会出现错误:

\n
struct A {\n    constexpr virtual ~A() = default;\n    constexpr A() = default;\n};\n\nstruct B : public A {\n    constexpr ~B() = default;\n    constexpr B() …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++20

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

您可以在编译时将 std::vector 转换为 std::array 而不使向量两次吗?

我正在编译时使用计算一些数据std::vector,并希望将结果作为数组返回,以便可以在运行时进一步使用。我在不进行两次计算的情况下设置数组大小时遇到​​问题。

这是我迄今为止所做的事情的简化示例。代码按预期编译并运行。

constexpr auto make_vector() { 
  // complex calculation here
  return std::vector{1, 2, 3}; 
}

constexpr auto make_array() {
  const auto vec = make_vector();
  std::array<int, make_vector().size()> result{};

  std::copy(vec.cbegin(), vec.cend(), result.begin());
  return result;
}

int main() {
  constexpr auto result = make_array(); // std::array<int, 3>{1, 2, 3}
}
Run Code Online (Sandbox Code Playgroud)

我理解为什么不能用于vec.size()数组大小以及为什么make_vector().size()会产生编译时常量。做两次似乎不是正确的方法。

有没有办法避免调用make_vector两次?我在这里错过了一个基本概念吗?

c++ constexpr c++20

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

嵌套结构尽管与全局结构完全相同但仍会破坏constexpr

我遇到以下代码时遇到问题:

template<typename T>
constexpr int get(T vec) {
  return vec.get();
}

struct coord {
  constexpr int get() const { return x; }
  int x;
};

struct foo {
    struct coord2 {
      constexpr int get() const { return x; }
      int x;
    };
    constexpr static coord f = { 5 };
    constexpr static int g = get(f); // works

    constexpr static coord2 h = { 5 };
    constexpr static int i = get(h); // doesn't work
};

constexpr coord foo::f;
constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

18
推荐指数
1
解决办法
375
查看次数

使用constexpr函数失败的模板实例化

我有一个模板类C,它具有类型的非类型但引用模板参数P:

class P {
public:
  int x;
  int y;
};

template <const P &x>
class C {
public:
  const int &f() { return x.x; }
};
Run Code Online (Sandbox Code Playgroud)

我声明了一个类型的全局变量P:

P p = {33,44};
Run Code Online (Sandbox Code Playgroud)

我还声明了一个返回引用的函数p:

constexpr const P &h() { return p; }
Run Code Online (Sandbox Code Playgroud)

然后尝试在下面使用这些:

C<p> o;    // line 1
C<h()> oo; // line 2
Run Code Online (Sandbox Code Playgroud)

当然我对第一次实例化没有问题,但第二次实例化没有问题.我的编译器抱怨:

error: non-type template argument does not refer to any declaration
Run Code Online (Sandbox Code Playgroud)

为什么会这样?我无法在常规中找到反对它的论据.我不确定它是否与在默认模板参数调用constexpr完全相同的问题,其中讨论是关于嵌套 instanciation的实例化点.这是一个类型问题,但哪一个?我的函数h()返回对定义良好的类型(const …

c++ templates language-lawyer constexpr c++11

18
推荐指数
2
解决办法
1250
查看次数

Constexpr放置新品?

C++标准特别禁止调用new常量表达式(N4296第5.20节[expr.const]):

条件表达式e是核心常量表达式,除非根据抽象机器(1.9)的规则评估e将评估以下表达式之一:

...

- 一个新表达式(5.3.4);

这项禁令(据我所知)延伸到所有形式new,包括新的安置.但是,由于placement new实际上并没有分配任何内存,只是在给定位置运行构造函数,并且因为在constexpr上下文中获取变量的地址是合法的(事实上​​,std::addressof在C++ 17中将是constexpr),似乎对我来说,这个禁令(原则上至少)可以放宽,以允许在constexpr功能中放置新的禁令.

所以我的问题是,我错过了什么吗?有没有一个很好的理由为什么在constexpr功能中禁止放置新的?

(对于上下文:当前规则几乎要求启用constexpr的sum类型std::variant实现为递归联合.能够使用类似std::aligned_storage和贴片new的东西会更好,但目前这是不可能的.)

c++ placement-new language-lawyer constexpr

18
推荐指数
1
解决办法
1215
查看次数