相关疑难解决方法(0)

constexpr重载

相关:函数返回constexpr无法编译

我觉得constexpr在C++ 11中的用处有限,因为无法定义两个本来具有相同签名的函数,但有一个是constexpr而另一个不是constexpr.换句话说,如果我有一个constexpr std :: string构造函数只接受constexpr参数,并且非constexpr std :: string构造函数用于非constexpr参数,那将非常有用.另一个例子是理论上复杂的功能,通过使用状态可以提高效率.使用constexpr函数你不能轻易做到这一点,所以你有两个选择:如果你传入非constexpr参数,那么constexpr函数非常慢,或者完全放弃constexpr(或写两个单独的函数,但你可能不知道要调用哪个版本).

因此,我的问题是:

是否有可能符合标准的C++ 11实现允许基于constexpr参数的函数重载,或者这需要更新标准?如果不允许,是否故意不允许?


@NicolBolas:假设我有一个映射enum到a 的函数std::string.最直接的方式做到这一点,假设我enum去从0n - 1,是创建一个大小的数组n充满了结果.

我可以创建一个static constexpr char const * []并构造一个std::string返回(std::string每次调用函数时支付创建对象的成本),或者我可以创建一个static std::string const []并返回我查找的值,std::string第一次支付所有构造函数的成本调用该函数.似乎更好的解决方案是std::string在编译时创建内存(类似于现在所做的char const *),但是执行此操作的唯一方法是警告构造函数它有constexpr参数.

对于一个除了std::string构造函数之外的例子,我认为找到一个例子是非常简单的,如果你可以忽略constexpr(并因此创建一个非constexpr函数)的要求,你可以创建一个更有效的函数.考虑一下这个帖子:constexpr问题,为什么这两个不同的程序用g ++在不同的时间内运行?

如果我fib用一个constexpr参数调用,我不能比编译器完全优化掉函数调用做得更好.但是,如果我fib使用非constexpr参数调用,我可能希望让它调用我自己的版本来实现memoization(这将需要状态)之类的东西,所以我得到的运行时间类似于我通过constexpr参数时的编译时间.

c++ overloading compile-time-constant constexpr c++11

45
推荐指数
5
解决办法
8601
查看次数

如何结合 constexpr 和矢量化代码?

我正在为 x64 和 neon 开发 C++ 内在包装器。我希望我的函数是 constexpr。我的动机类似于Constexpr 和 SSE 内在函数,但是 #pragma omp simd 和内在函数在 constexpr 函数中可能不受编译器 (GCC) 的支持。下面的代码只是一个演示(自动矢量化对于加法来说已经足够了)。

struct FA{
    float c[4];
};

inline constexpr FA add(FA a, FA b){
    FA result{};
    #pragma omp simd            // clang error: statement not allowed in constexpr function
    for(int i = 0; i < 4; i++){ // GCC error: uninitialized variable 'i' in 'constexpr' function
        result.c[i] = b.c[i] + a.c[i];
    }
    return result;
}
struct FA2{
    __m128 c;
};


inline constexpr …
Run Code Online (Sandbox Code Playgroud)

c++ openmp intrinsics constexpr

7
推荐指数
1
解决办法
178
查看次数

在 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
查看次数