相关疑难解决方法(0)

在C++ 11中is_constexpr是否可行?

是否有可能根据C++ 11中的C++ 11表达式是否为常量表达式(即constexpr)生成编译时布尔值?关于SO的几个问题与此有关,但我在任何地方都没有看到直接答案.

c++ compile-time constexpr c++11

32
推荐指数
4
解决办法
3946
查看次数

做constexpr运算符重载的指南?

考虑一个简单的INT Wrapper与重载乘法类operator*=operator*.对于"旧式"运算符重载,可以定义operator*,operator*=甚至还有像Boost.Operators这样的库以及@DanielFrey的现代化版本操作,它们可以为您减少样板.

但是,对于使用新C++ 11的编译时计算constexpr,这种便利性消失了.A constexpr operator*无法调用,operator*=因为后者修改了它的(隐式)左参数.此外,constexpr没有过载,因此constexpr operator*在现有operator*结果中添加额外的过载分辨率模糊.

我目前的做法是:

#include <iostream>

struct Wrap
{
    int value;    

    Wrap& operator*=(Wrap const& rhs) 
    { value *= rhs.value; return *this; }

    // need to comment this function because of overloading ambiguity with the constexpr version
    // friend Wrap operator*(Wrap const& lhs, Wrap const& rhs)
    // { return Wrap { …
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading constexpr c++11 c++14

26
推荐指数
1
解决办法
6480
查看次数

实现is_constexpr_copiable

我试图实现一个类似于std::is_constructible异常的值模板,只有当类型在constexpr环境中可复制时才是真的(即它的复制构造函数是constexpr限定的).我到达了以下代码:

#include <type_traits>

struct Foo {
    constexpr Foo() = default;
    constexpr Foo(const Foo&) = default;
};
struct Bar {
    constexpr Bar() = default;
    Bar(const Bar&);
};

namespace detail {
template <int> using Sink = std::true_type;
template<typename T> constexpr auto constexpr_copiable(int) -> Sink<(T(T()),0)>;
template<typename T> constexpr auto constexpr_copiable(...) -> std::false_type;
}
template<typename T> struct is_constexpr_copiable : decltype(detail::constexpr_copiable<T>(0)){ };

static_assert( is_constexpr_copiable<Foo>::value, "");
static_assert(!is_constexpr_copiable<Bar>::value, "");
Run Code Online (Sandbox Code Playgroud)

现在我问自己这是否符合标准,因为编译器似乎不同意输出. https://godbolt.org/g/Aaqoah


编辑(c ++ 17功能):

is_constexpr_constructible_from使用c ++ 17的新的自动非类型模板类型实现稍微不同的时候,我再次发现编译器之间的区别,当在constexpr表达式中取消引用nullptr时SFINAE.

#include <type_traits>

struct Foo …
Run Code Online (Sandbox Code Playgroud)

c++ templates language-lawyer constexpr c++17

22
推荐指数
1
解决办法
527
查看次数

在编译期间或运行时确定`constexpr`执行?

有没有办法constexpr在编译阶段和运行时实现函数的不同行为?

考虑以下示例(使用理论特征D: static if):

constexpr int pow( int base , int exp ) noexcept
{
    static if( std::evaluated_during_translation() ) {
        auto result = 1;
        for( int i = 0 ; i < exp ; i++ )
            result *= base;
        return result;
    } else { // std::evaluated_during_runtime()
        return std::pow( base , exp );
    }
}
Run Code Online (Sandbox Code Playgroud)

如果没有,有没有办法限制constexpr只编译时间?

c++ constexpr c++14

14
推荐指数
2
解决办法
492
查看次数

constexpr,static_assert和inlining

我之前根据参数是否constexpr询问函数重载.我正试图解决这个问题的令人失望的答案,以建立一个更聪明的断言功能.这大致是我想做的事情:

inline void smart_assert (bool condition) {
    if (is_constexpr (condition))
        static_assert (condition, "Error!!!");
    else
        assert (condition);
}
Run Code Online (Sandbox Code Playgroud)

基本上,我们的想法是编译时检查总是比运行时检查更好,如果可以在编译时检查.但是,由于内联和常量折叠之类的东西,我不能总是知道是否可以进行编译时间检查.这意味着可能存在assert (condition)编译的情况,assert(false)代码只是等待我运行它并在我发现错误之前执行该路径.

因此,如果有某种方法来检查条件是否是constexpr(由于内联或其他优化),我可以static_assert在可能的情况下调用,否则返回运行时断言.幸运的是,gcc具有内在函数__builtin_constant_p (exp),如果exp是constexpr 则返回true .我不知道其他编译器是否有这种内在的,但我希望这可以解决我的问题.这是我提出的代码:

#include <cassert>
#undef IS_CONSTEXPR

#if defined __GNUC__
    #define IS_CONSTEXPR(exp) __builtin_constant_p (exp)
#else
    #define IS_CONSTEXPR(exp) false
#endif
// TODO: Add other compilers

inline void smart_assert (bool const condition) { 
    static_assert (!IS_CONSTEXPR(condition) or condition, "Error!!!");
    if (!IS_CONSTEXPR(condition))
        assert (condition);
}

#undef IS_CONSTEXPR
Run Code Online (Sandbox Code Playgroud)

static_assert …

c++ inline static-assert constexpr c++11

13
推荐指数
2
解决办法
4713
查看次数

我可以在编译时检测到编译时常量的"函数参数"

我可以在编译时检测"函数参数" 1是否是编译时常量?

例如,一个函数print(int i)可以"constant 5"在被调用时打印,print(5)"non-constant 5"如果被调用为print(i)where,i则是一些非常量变量.特别是,在"is constant"分支中,我应该能够将其i视为constexpr,包括将其用于模板参数等.

宏技巧,模板元编程和SFINAE技巧都可以.理想情况下它是可移植的,但是编译器特定的解决方案总比没有好.

如果存在"错误否定"则可以 - 即,如果常量值有时被检测为非常数(例如,禁用某些优化时).

如果解决方案可以检测到常量值何时间接传递给函数(例如,当一个常量值传递给调用的中间函数print并且随后内联将常量暴露给print)时,可以获得奖励积分.最后一种行为显然取决于优化.

如果它自然延伸到多个参数,则可获得双倍奖励

如果一个人可以使用和不带constexpr参数重载函数的版本,这可能是直截了当的,但你不能.


1我在这里引用"函数参数",因为解决方案并不严格要求在函数内(或在具有特殊参数的调用者/被调用者边界)检测此状态 - 它只需要像函数一样出现给调用者但是可以使用宏或其他技巧,如静态对象operator()等.

c++ optimization constexpr c++11

12
推荐指数
1
解决办法
885
查看次数

constexpr问题,为什么这两个不同的程序用g ++在这么不同的时间内运行?

我正在使用gcc 4.6.1并且正在获得一些涉及调用constexpr函数的有趣行为.这个程序运行得很好,直接打印出来12200160415121876738.

#include <iostream>

extern const unsigned long joe;

constexpr unsigned long fib(unsigned long int x)
{
   return (x <= 1) ? 1 : (fib(x - 1) + fib(x - 2));
}

const unsigned long joe = fib(92);

int main()
{
   ::std::cout << "Here I am!\n";
   ::std::cout << joe << '\n';
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这个程序需要永远运行,我从来没有耐心等待它打印出一个值:

#include <iostream>

constexpr unsigned long fib(unsigned long int x)
{
   return (x <= 1) ? 1 : (fib(x - 1) + …
Run Code Online (Sandbox Code Playgroud)

c++ g++ constexpr c++11

11
推荐指数
1
解决办法
796
查看次数

返回constexpr的函数无法编译

为什么不编译:作为返回类型
会出现问题string吗?

constexpr std::string fnc()
{
    return std::string("Yaba");
}
Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors constexpr c++11

11
推荐指数
1
解决办法
1732
查看次数

如果在编译时未知表达式,则通过静态断言

我想实现my_static_assert与c ++ 17单参数稍有不同的方法static_assert:如果在编译时my_static_assert 不知道里面的条件,则应该通过

my_static_assert以下示例中的第二个应该通过,但是如果我使用static_assert它将会失败。

#include <iostream>

int x, y;
constexpr int f1() { return 0; }
constexpr int f2() { return 0; }
int f3() { return x; }
int f4() { return y; }
constexpr int sum(int a, int b) { return a + b; }

int main() {
    std::cin >> x >> y;

    // it should fail 
    my_static_assert(sum(sum(f1(), f2()), sum(f1(), f1())) != 0);

    // it should …
Run Code Online (Sandbox Code Playgroud)

c++

11
推荐指数
1
解决办法
219
查看次数

Constexpr和SSE内在函数

大多数C++编译器都支持SIMD(SSE/AVX)指令

_mm_cmpeq_epi32
Run Code Online (Sandbox Code Playgroud)

我的问题是这个函数没有标记为constexpr,虽然"语义上"没有理由不使用这个函数,constexpr因为它是一个纯函数.

有什么办法,我可以写我自己的版本(例如)_mm_cmpeq_epi32constexpr

显然我希望运行时的函数使用正确的asm,我知道我可以重新实现具有慢速函数的任何SIMD函数constexpr.

如果你想知道为什么我关心constexprSIMD功能.非constexprness具有传染性,这意味着我的任何使用SIMD功能的功能都不可能constexpr.

c++ sse simd intrinsics constexpr

9
推荐指数
1
解决办法
721
查看次数

`constexpr` 函数的 `noexcept` 行为

[expr.unary.noexcept]的措辞在C++17 中发生了变化。


以前(n4140, 5.3.7 noexcept operator [expr.unary.noexcept]),我的重点是

  1. 如果在潜在求值的上下文中表达式将包含,则 noexcept 运算符的结果为 false

    (3.1) 对不具有非抛出异常规范 ([except.spec]) 的函数、成员函数、函数指针或成员函数指针的潜在求值调用,除非调用是常量表达式 ([ expr.const]) ...


现在17.6.2.6 noexcept 运算符 [expr.unary.noexcept]):

  1. 除非表达式可能抛出异常 ([except.spec]),否则noexcept 运算符的结果为

然后在14.5 异常规范 [except.spec] 中

  1. 如果函数声明没有 noexcept 说明符,则该声明具有潜在的抛出异常说明,除非...

但是14.5(3)的除非列表未列出constexpr,因此可能会抛出...

1 LF 在评论中添加的指向 C++17 n4659的链接。


测试代码

constexpr int f(int i) { return i; }

std::cout << boolalpha << noexcept(f(7)) << std::endl;
int a = 7;
std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer noexcept constexpr c++17

8
推荐指数
1
解决办法
260
查看次数

C ++ constexpr重载,用于编译时和运行时的不同代码

constexpr void X() {
  /* code, that can be executed at compiletime */
}

void X() {
  /* code, that does the same as above, but is optimized for runtime, eg.
  including caching, assembler code, ... to optimize runtime performance */
}
Run Code Online (Sandbox Code Playgroud)

如上所示,我想要两个函数,它们基本上都在做相同的事情,一个针对运行时进行了优化,一个针对编译时进行了优化。在我的示例中,运行时版本涉及缓存,这不能在constexpr中完成,但可以提高运行时的性能。

可以通过某种方式(使用C ++ 14)实现吗?

如果只能使用特定于编译器的解决方案来实现此目的,那么它们也可以,但是我更喜欢一种标准解决方案(当前,我不知道有一个解决方案)

c++ optimization constexpr c++14

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