标签: constexpr

C++中的const double表达式

C++ 11英文维基百科页面中,我们可以读到:

在C++ 11之前,仅当变量声明为const,初始化程序是常量表达式并且是整数或枚举类型时,变量的值才能用于常量表达式.如果使用constexpr关键字定义变量,则 C++ 11 将删除变量必须为整数或枚举类型的限制:

 constexpr double earth_gravitational_acceleration = 9.8;
 constexpr double moon_gravitational_acceleration = earth_gravitational_acceleration / 6.0;
Run Code Online (Sandbox Code Playgroud)

这是什么意思?特别是,它是否意味着:

const double earth_gravitational_acceleration = 9.8;
const double moon_gravitational_acceleration = earth_gravitational_acceleration / 6.0;
Run Code Online (Sandbox Code Playgroud)

在C++ 11之前的C++中是非法的?G ++与此完全OK,即使有-ansi,-pedantic等...

谢谢!

c++ const constexpr

2
推荐指数
1
解决办法
2万
查看次数

如何将此运行时效率函数转换为constexpr?

我正在使用C++ constexpr在编译时评估此代码可以正确评估的计算的Fibonacci序列的最大项.为此,我使用以下代码:

constexpr unsigned long long fibo(unsigned n) {
    return (n < 2) ? 1 : fibo(n-1)+fibo(n-2);
}

constexpr unsigned max_fibo(unsigned n) {
    return (fibo(n+1) >= fibo(n)) ? max_fibo(n+1) : n;
}

const unsigned MAX_FIBO_TERM = max_fibo(0);
Run Code Online (Sandbox Code Playgroud)

这很好,并快速构造MAX_FIBO_TERM(我的机器上的92)正确的值.但是,使用该fibo函数在运行时实际计算项是非常慢的(仅计算前48个项需要大约90秒).

我可以使用替代函数来计算更快的术语:

unsigned long long fiboiter(unsigned n, unsigned long long &prev, 
                            unsigned long long &prevprev) {
    return prev = (n < 2) ? prevprev = 1 : 
        (std::swap(prev, prevprev), prev + prevprev);
}
Run Code Online (Sandbox Code Playgroud)

但是,我似乎无法将其变为有效的constexpr功能.(这就是为什么它以那种奇怪的方式写的.)当我运行这个版本时,我的机器需要0.005秒.

当我用g++ …

c++ fibonacci constexpr c++11

2
推荐指数
1
解决办法
216
查看次数

没有参数的constexpr函数

我对这个片段感到困惑:

constexpr int f(bool b) {
  return b ? throw 0 : 0; }
constexpr int f() { return f(true); }
Run Code Online (Sandbox Code Playgroud)

直接来自c ++草案.我所强调的一点是,为什么标准将constexpr没有参数的函数定义为格式错误(在同一链接中说明).愿有人澄清吗?

c++ constexpr c++11

2
推荐指数
1
解决办法
88
查看次数

如何防止constexpr功能的意外发射

Ben Deane提到了throw技巧,它确保在非constexpr上下文中使用constexpr函数时出现链接错误.

这是我的看法:

#include <iostream>

struct Exc;

constexpr int foo( int a )
{
    if( a == 42 )
    {
        throw Exc{};
    }

    return 666;
}


int main()
{
    constexpr auto ret = foo(43);
    std::cout << ret << "\n";

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

但我无法使它工作(clang ++ 3.8.1-23和g ++ 6.3.0):

$ clang++ -std=c++14  main.cpp 
main.cpp:9:15: error: invalid use of incomplete type 'ExcBase'
        throw ExcBase{};
              ^~~~~~~~~
main.cpp:3:8: note: forward declaration of 'ExcBase'
struct ExcBase;
       ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

这个帖子中的评论暗示了另一个技巧:

#include <iostream> …
Run Code Online (Sandbox Code Playgroud)

constexpr c++14

2
推荐指数
1
解决办法
210
查看次数

如何在静态constexpr类成员中使用make_tuple()?

我想用make_tuple()constexpr.它适用于全球范围.但它会为static constexpr类成员生成链接错误.

#include <iostream>
#include <tuple>

using namespace std;

class A
{
public:
    static constexpr auto z = make_tuple(5, 3.0);
};

constexpr auto tp = make_tuple(6, 3.2);

int main()
{

    cout << get<0>(tp) << " " << get<1>(tp) << endl; // OK

    cout << get<0>(A::z) << "  " << get<1>(A::z) << endl; // error: (.text+0x5a): undefined reference to `A::z'
                                                          //        (.text+0x67): undefined reference to `A::z'

}
Run Code Online (Sandbox Code Playgroud)

我已经检查了这里 make_tuple本身不是constexprc++11.我猜这不是问题.如果是,它将生成编译错误而不是链接错误. …

c++ constexpr c++11

2
推荐指数
1
解决办法
549
查看次数

斐波那契和'if constexpr'

请考虑以下代码:

template<int nIndex>
int Fibonacci()
{
    if constexpr (nIndex == 0) return 0;
    if constexpr (nIndex == 1) return 1;

    static_assert(nIndex >= 0, "Invalid index passed to Fibonacci()");
    return Fibonacci<nIndex - 1>() + Fibonacci<nIndex - 2>();
}

int main()
{
    Fibonacci<3>(); // 2
    //Fibonacci<-1>();  // Fires assertion 

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

当我在VS2017中运行它时,编译器输出:

error C2338: Invalid index passed to Fibonacci()
note: see reference to function template instantiation 'int Fibonacci<-1>(void)' being compiled
note: see reference to function template instantiation 'int Fibonacci<1>(void)' being compiled …
Run Code Online (Sandbox Code Playgroud)

c++ templates if-statement constexpr c++17

2
推荐指数
1
解决办法
186
查看次数

为什么我收到此错误:constexpr'在这里无效

我有这个代码:

class myClass
{
        constexpr int x = 4;
};
Run Code Online (Sandbox Code Playgroud)

在visual studio 2015上,我收到此错误:

'constexpr' is not valid here
Run Code Online (Sandbox Code Playgroud)

为什么我收到此错误?我想要一个const静态变量,我可以在头文件中初始化它.

在下一步中,我想将我的类更改为模板,但此常量与clas的类型无关.

c++ constexpr c++11 visual-studio-2015

2
推荐指数
1
解决办法
1796
查看次数

强制将表达式表达为constexpr

给定两个constexpr功能,是否可以将它们组合为一个功能?

template <char... C>
constexpr int boo()
{
    char ch[] = { C... };
    int count = 0;

    for (char c : ch)
    {
        if (c != '0') count += 1;
    }

    return count;
}

template <char... C>
constexpr auto foo()
{
    std::array<char, boo<C...>()> x{};

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

如示例所示,我可以将' count'作为常量返回。我的问题是我不能count在声明的函数中使用' '作为常量。也就是说,如果将' boo()' 的主体放在' foo()'中,则编译器将抛出' count'不是常量。

c++ template-meta-programming variadic-templates constexpr c++17

2
推荐指数
1
解决办法
103
查看次数

is_constant_evaluated()应该产生constexpr变量吗?

我已经阅读了std::is_constant_evaluated()定义,但是我仍然不确定为什么(1)无法在最新的GCC上运行error: 'x' is not a constant expression

template<auto v>
struct s
{};

constexpr void f(int x)
{
    if (std::is_constant_evaluated())
    {
        // constexpr int z=x; (1)
        // s<x> a; (2)
    }
}

int main(int argc, char* argv[])
{
    f(4);
    //f(argc);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
  1. 按照标准,这行得通吗?
  2. 还是仅GCC实施存在问题?
  3. 我如何才能达到预期的行为?基本上是:

随着分支 std::is_constant_evaluated()

  • 如果为真:代码可以将变量用作constexpr(如(2))
  • 如果为假:代码使用变量作为非constexpr

更新

我可以将“解释性”信息“传输”到函数中吗?基本上决定f()是否使用constexprx 进行调用。

UPDATE 关于我要实现的目标的一个更复杂的示例:如果可能,此示例应在编译时对参数进行字符串化。

template<auto v>
struct dummy_stringify
{
    static constexpr auto str=v==4 ? "4" : "31"; // this is just …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++20

2
推荐指数
1
解决办法
200
查看次数

如何使编译器警告这是无效布尔值?

我们只是被错字弄糊涂了:“ constexpr bool maxDistance = 10000;

gcc和clang都编译此文件而没有任何警告。

真正的错误是该变量不应为bool类型,而应为整数类型。

我们如何确保将来收到编译器警告?

#include <iostream>

constexpr bool number = 1234;
int main(int argc, char* argv[])
{
    std::cout << number + 10000 << std::endl; // prints 10001.
    return number;
}
Run Code Online (Sandbox Code Playgroud)

这里的错误是变量声明的类型错误,但是clang和gcc均未给出警告。

gcc -Wall -std=c++14 test.cpp -lstdc++
clang -Wall -std=c++14 test.cpp -lstdc++
Run Code Online (Sandbox Code Playgroud)

(使用gcc 5.4.0和clang 3.8.0)

注意:此后,我已经了解了一个可能的编译标志:-Wint-in-bool-context但是,这似乎在我使用的版本(5.4.0)和clang(3.8.0)中均未实现。

这是正确的方法吗?

c++ boolean compiler-warnings constexpr

2
推荐指数
1
解决办法
95
查看次数