标签: constexpr

在编译时初始化 c++ std::bitset

我试图std::bitset<256>在编译时用它的一些索引初始化 a ,比如 50-75 和 200-225 设置为 1。

基于http://en.cppreference.com/w/cpp/utility/bitset/bitset 看起来我的 2 个选项是:

constexpr bitset();
constexpr bitset( unsigned long long val ); 
Run Code Online (Sandbox Code Playgroud)

考虑到第二个构造函数不适用于大型索引,有人可以阐明我将如何初始化我的位集吗?

c++ templates constexpr c++11

5
推荐指数
1
解决办法
3336
查看次数

在 constexpr 评估上分支/在 constexpr 上重载

设置:

我有一个使用 SIMD 内在函数的函数,并希望在一些 constexpr 函数中使用它。

为此,我需要使其成为 constexpr。但是,SIMD 内在函数没有标记为 constexpr,编译器的常量评估器无法处理它们。

我尝试用执行相同操作的 C++ constexpr 实现替换 SIMD 内在函数。该函数在运行时变慢了 3.5 倍,但我能够在编译时使用它(是吗?)。

问题

如何在常量表达式中使用此函数而不会在运行时减慢程序速度?

一些想法:

  • 为所有编译器添加对编译器常量表达式求值器的常量求值所有 SIMD 内在函数的支持:可能是正确的解决方案,但这是一项不可能完成的任务。

更务实的解决方案是:

  • 重载函数取决于它是否在常量表达式中执行(即提供 constexpr 和非 constexpr 版本)。
  • 或者,在 constexpr 和运行时实现之间的 constexpr 函数内以某种方式分支(即,在分支中检测函数是否在常量表达式内执行)。

无论如何,我愿意接受任何解决我问题的建议。

提示

  • @RMartinhoFernandes 在 Lounge 中建议使用__builtin_constant_p来检测函数参数是否都是常量表达式,在这种情况下,编译器希望至少尝试在编译时评估函数。

失败的尝试

  • @ Jarod42 提出了只使用两个独立函数的直接建议。我想简单地指出为什么这行不通,因为它不是微不足道的。该解决方案假设在调用站点知道函数是否会被 constexpr 评估。但这种情况并非如此。考虑一个调用我的函数的 constexpr 函数,它应该选择哪个版本的函数?它必须选择 constexpr 一个才能编译,但“外部” constexpr 函数仍然可以在运行时评估。在这种情况下,它将使用“慢”编译时实现,因此,这种方法不能解决问题。

c++ simd intrinsics constexpr c++14

5
推荐指数
1
解决办法
832
查看次数

编译时消息测试constexpr

当对编译时 constexpr 的测试评估为真时,是否可以打印消息?像 static_assert 这样的东西而不停止编译器。

constexpr Application::Mode SETUP_MODE = Application::Debug;

// Can I somehow test if the SETUP_MODE is debug for pragma message?
#pragma message("Application mode is set to Debug!")

static_assert(SETUP_MODE != Application::Debug, 
    "Application mode is set to Debug!"); // Can I somehow just print this message without aborting the compilation?
Run Code Online (Sandbox Code Playgroud)

c++ static-assert constexpr c++14

5
推荐指数
0
解决办法
598
查看次数

将 `hana::string` 转换为 `constexpr const char (&amp;)[]`

我有一些旧代码使用与这里这里str_const描述的非常相似的东西来执行一些 constexpr 字符串操作。是 Scott Schurr 描述的文字类型,可以从字符串文字构造,因为它有一个来自.str_constconst char (&)[]

我现在也有一些使用boost::hana.

我希望能够使用 ahana::string并创建一个str_const引用它的。最简单的方法是将 a 转换hana::string为 a constexpr const char (&)[]。(实际上,在这一点上这不是最简单的方法,最简单的方法肯定是在我的str_const实现中添加一个新的模板构造函数。但在这一点上,这个问题已经有了它自己的生命,我主要感兴趣的是这是否可以用 来完成hana::string。所以让我们假设我不允许更改str_const实现。)

但是,在hana 文档中,转换hana::string为运行时字符串的方法是hana::to<const char *>.

乐观地,我尝试了各种形式,hana::to<const char (&)[hana::length(...)]> (...)但这会导致静态断言hana失败。

hana文档建议的另一个选项是使用hana::unpack然后自己将字符粘贴到数组中。我写了这段代码

template <typename T, size_t N>
struct array {
  T arr[N];
};

struct char_packer {
  template <typename... Ts> …
Run Code Online (Sandbox Code Playgroud)

c++ string constexpr c++14 boost-hana

5
推荐指数
1
解决办法
486
查看次数

平凡的默认构造函数不能是 constexpr 吗?

看起来 C++ 标准当前阻止普通默认构造函数成为 constexpr(如果有任何非静态成员变量),因为普通默认构造函数必须什么都不做,但 constexpr 构造函数必须初始化所有内容。不幸的是,这会阻止该类型成为 POD 类型。

是否有任何解决方法可以允许类类型具有可在 constexpr 代码中使用的默认构造函数,而不会使类成为非 POD?

我可以通过向构造函数添加一个冗余参数来解决这个问题,以便 constexpr 代码可以使用非默认构造函数,但这看起来很脏,尤其是因为在我关心的情况下,初始化值是不必要的,并且都将被写入-over 在后面的代码中,所以我更喜欢一个简单的默认构造函数。例如:

struct A {
    int a;

    // Non-default constructors necessitate an explicit default
    // constructor if default constructor is to exist
    constexpr A(int b) : a(b) {}

#if 1 // non-POD
    // constexpr default constructor must initialize everything,
    // but this makes A non-POD.
    constexpr A() : a(0) {}
#else // Workaround
    A() = default;
    struct UnnecessaryClass {};
    constexpr A(UnnecessaryClass) : a(0) {}
#endif
}; …
Run Code Online (Sandbox Code Playgroud)

c++ constructor constexpr

5
推荐指数
1
解决办法
1278
查看次数

静态 constexpr 模板成员在专门化时给出未定义的引用

以下代码给出了未定义的引用链接错误:

template<int>
struct X {
    static constexpr int x = 0;
};

template<>
constexpr int X<1>::x;

int main() 
{   
    return X<1>::x;
}
Run Code Online (Sandbox Code Playgroud)

但我不知道确切的原因。

是否可以在不专门化整个模板的情况下定义数据成员?

需要明确的是:这段代码编译得很好,但会出现链接器错误(未定义引用)。

c++ templates linker-errors constexpr

5
推荐指数
1
解决办法
1163
查看次数

Constexpr operator new

Is it possible to overload the operator new to be constexpr function? Something like:

constexpr void * operator new( std::size_t count );
Run Code Online (Sandbox Code Playgroud)

The reason why would be to execute constexpr function within the overloaded operator body where count argument value would be an input data... As the operator is invoked by:

SomeClass * foo = new SomeClass(); 
Run Code Online (Sandbox Code Playgroud)

The size of the data type is know at compile time, isn’t it? (count== sizeof(SomeClass)) So the count can be considered …

c++ constexpr c++17 if-constexpr

5
推荐指数
1
解决办法
1584
查看次数

constexpr 函数内的静态表

我有一段将整数映射到整数的生成代码,其核心是一个简单的表。在 C++17 之前,它曾经是这样的:

int convert (int v)
{
  static const int table[] = { 3, 2, 6, 1, 7, 1, 6, 8 };

  if (0 <= v && v < sizeof table / sizeof table[0])
    return table[v];
  else
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

使用 C++17,我想使用 constexpr。我预计增加constexpr的函数签名就足够了,但我要删除static表,这让我实施显然没有很好的理由更加复杂。没有太多提及,table在非constexpr情况下很可能会在堆栈上,所以我想我应该更换 staticconstexpr

G++ 8 报告:

/tmp/foo.cc: In function 'constexpr int convert(int)':
/tmp/foo.cc:14:26: error: 'table' declared 'static' in 'constexpr' function
   static const int table[] = { …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++17

5
推荐指数
1
解决办法
572
查看次数

c ++ 14 静态 constexpr 自动与 odr 用法

我有以下 c++14 代码:

template<typename T>
struct Test{
    static constexpr auto something{T::foo()};
};
Run Code Online (Sandbox Code Playgroud)

这完全没问题,前提是它T::foo()也是一个constexpr

现在我已经使用了somethingODR,所以我需要提供一个命名空间声明。我应该使用什么语法?

template<typename T>
constexpr auto Test<T>::something;
Run Code Online (Sandbox Code Playgroud)

不起作用。谢谢!

c++ templates constexpr auto c++14

5
推荐指数
1
解决办法
203
查看次数

const_cast 在常量表达式中是否有效?(C++14, C++17)

a 遇到的具体问题是编译器处理它的方式存在一些不一致。

例如这个代码(https://godbolt.org/z/08Z-zi):

    constexpr auto value = 1;
    static_assert(*const_cast<int *>(&value), "value should be 1");
Run Code Online (Sandbox Code Playgroud)

使用 GCC、Clang 和 MSVC 编译良好,但使用英特尔 C++ 编译器 19.0.1 失败并出现以下错误:

error: expression must have a constant value
static_assert(*const_cast<int *>(&value), "value should be 1");
Run Code Online (Sandbox Code Playgroud)

据我所知,标准没有明确说明const_cast常量表达式中不允许使用 a。通过结果指针写入将是未定义的,因此不允许,但读取应该没问题。

考虑到所有主要编译器都会编译此代码(包括 ICC < 19.0.1),这可能只是 ICC 19.0.1 中的回归。

c++ const-cast language-lawyer constant-expression constexpr

5
推荐指数
1
解决办法
265
查看次数