标签: constexpr

constexpr真的需要吗?

我一直在constexpr研究C++ 的新功能,但我并不完全理解它的必要性.

例如,以下代码:

constexpr int MaxSize()
{
    ...

    return ...;
}

void foo()
{
    int vec[MaxSize()];
}
Run Code Online (Sandbox Code Playgroud)

可以替换为:

int MaxSize()
{
    ...

    return ...;
}

static const int s_maxSize = MaxSize();

foo()
{
    int vec[s_maxSize];
}
Run Code Online (Sandbox Code Playgroud)

更新

第二个例子实际上不是标准的ISO C++(感谢几个用户指出这一点),但某些编译器(例如gcc)支持它.因此,这不是const使程序有效,而是gcc支持这种非标准功能的事实.(据我所知,只有当数组被定义为函数或方法的本地数据时才有可能,因为在编译时必须知道全局数组的大小.)如果我编译没有选项-std=c++98 -pedantic-errors,甚至代码

int MaxSize()
{
    return 10;
}

void foo()
{
    int vec[MaxSize()];
}
Run Code Online (Sandbox Code Playgroud)

将使用gcc编译.

因此,考虑到目前为止的反馈(以及我在同一时间进行的一些进一步阅读),我将尝试重新解释我的问题.

const大量使用关键字.随着const我可以定义有其整个生命周期内某一特定值的常数.可以使用任何表达式初始化常量,该表达式被计算一次,即创建常量时.对于这些情况,我认为这constexpr是非常无用的:它将引入一个非常小的优化,因为定义常量值的表达式将在编译时而不是运行时计算.每次我需要一个复杂初始化的运行时常量时我都会使用关键字const.

因此constexpr,在我们需要在编译时初始化常量的情况下,可能会派上用场.一个示例是矢量定义:标准不支持在运行时定义大小.另一个示例是具有一个或多个非类型参数的模板.

在这种情况下,我通常使用宏:

#define MAX_SIZE (10)

void foo()
{
    int …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

16
推荐指数
3
解决办法
6217
查看次数

对于静态const getter,内联vs constexpr?

在下面的代码中,哪个函数可以为外部使用提供最佳优化,为什么?C++ 2011中是否允许"版本4"?

template<unsigned int TDIM> class MyClass 
{
    public:
        static inline unsigned int size()           {return _size;} // Version 1
        static inline const unsigned int size()     {return _size;} // Version 2
        static constexpr unsigned int size()        {return _size;} // Version 3
        static inline constexpr unsigned int size() {return _size;} // Version 4
    protected:
        static const unsigned int _size = TDIM*3;
};
Run Code Online (Sandbox Code Playgroud)

非常感谢你.

c++ inline constexpr c++11

16
推荐指数
1
解决办法
2593
查看次数

空的析构函数vs文字析构函数

请考虑以下代码:

#include <iostream>

class Test
{
    public:
        constexpr Test(const int x) : _x(x) {}
        constexpr int get() const {return _x;}
        ~Test() {} // HERE
    protected:
        const int _x;
};

int main()
{
    static constexpr Test test(5);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我删除该行HERE代码编译得很好,但是如果我定义一个空的析构函数,则会导致编译错误,说明Test它是非文字的.

为什么空的析构函数和没有析构函数之间有什么区别呢?

编辑:另一个相关的问题:如果空和文字析构函数不同如何定义受保护的文字析构函数?

c++ destructor user-defined-literals constexpr c++11

16
推荐指数
1
解决办法
2126
查看次数

在constexpr抛出的异常中使用副作用是否合法?

通常,constexpr必须没有副作用.但是,我刚刚发现可以在抛出异常的构造函数中使用副作用.该技术可用于模拟constexpr函数的assert(),如下面的程序所示.

#include <iostream>
#include <cstdlib>
#include <stdexcept>

struct constexpr_precond_violated : std::logic_error
{
  constexpr_precond_violated(const char* msg) :
    std::logic_error(msg)
  {
    std::cerr << msg << '\n';
    abort(); // to get a core dump
  }
};

#define TO_STRING_IMPL(x) #x
#define TO_STRING(x) TO_STRING_IMPL(x)

#define CONSTEXPR_PRECOND(cond, value) \
  ((!(cond)) ? throw constexpr_precond_violated( \
    "assertion: <" #cond "> failed (file: " \
    __FILE__ ", line: " TO_STRING(__LINE__) ")")    \
   : (value))

constexpr int divide(int x, int y)
{
  return CONSTEXPR_PRECOND(y != 0, x / y);
}

int …
Run Code Online (Sandbox Code Playgroud)

c++ assert language-lawyer constexpr c++11

15
推荐指数
1
解决办法
732
查看次数

关于常量表达式的困惑

这是本主题的某种后续行动,涉及其中的一小部分.与前一个主题一样,让我们​​考虑一下我们的编译器有和的constexpr函数.现在,让我们直截了当地说.std::initializer_liststd::array

这有效:

#include <array>
#include <initializer_list>

int main()
{
    constexpr std::array<int, 3> a = {{ 1, 2, 3 }};
    constexpr int a0 = a[0];
    constexpr int a1 = a[1];
    constexpr int a2 = a[2];
    constexpr std::initializer_list<int> b = { a0, a1, a2 };

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

这不是:

#include <array>
#include <initializer_list>

int main()
{
    constexpr std::array<int, 3> a = {{ 1, 2, 3 }};
    constexpr std::initializer_list<int> b = { a[0], a[1], a[2] …
Run Code Online (Sandbox Code Playgroud)

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

15
推荐指数
1
解决办法
2418
查看次数

下载时是否必须使用constexpr数组?

给出以下代码:

struct A { static constexpr int a[3] = {1,2,3}; };

int main () {
  int a = A::a[0];
  int b  [A::a[1]];
}
Run Code Online (Sandbox Code Playgroud)

A::a必然使用的ODRint a = A::a[0]


注意:这个问题代表了休息室辩论的一个不那么闷热/不合逻辑/无穷无尽的版本.

c++ language-lawyer constexpr c++11

15
推荐指数
3
解决办法
1336
查看次数

为什么不是abs constexpr?

<cinttypes>,从C++ 11开始,有以下两个重载:

std::intmax_t abs( std::intmax_t n );
std::intmax_t imaxabs( std::intmax_t n );
Run Code Online (Sandbox Code Playgroud)

为什么不是这两个功能constexpr

c++ constexpr c++11

15
推荐指数
2
解决办法
2134
查看次数

使用constexpr编译时间字符串加密

我想要一个编译时字符串加密,这样我就可以在我的代码中编写:

const auto encryptedInvalidLicense = ENCRYPT("Invalid license");
std::cout << encryptedInvalidLicense.decrypt() << std::endl; // outputs "Invalid license"
Run Code Online (Sandbox Code Playgroud)

并且字符串"Invalid license"不会出现在二进制文件中.预构建可能是答案,但我正在寻找一个纯c ++ constexpr解决方案来解决这个问题,它将得到VS2015的支持.

有什么建议?


  1. 我已经研究过编译时字符串加密,它没有为问题提供constexpr解决方案.

  2. 我还研究了http://www.unknowncheats.me/forum/c-and-c/113715-compile-time-string-encryption.html.虽然它是一个constexpr解决方案,但VS2015仍然将字符串纯文本添加到二进制文件中.

c++ reverse-engineering constexpr c++11 c++14

15
推荐指数
1
解决办法
5835
查看次数

虚函数可以是constexpr吗?

可以X::f()在下面的代码中使用虚函数

struct X 
{
    constexpr virtual int f() const 
    {
        return 0;
    }
};
Run Code Online (Sandbox Code Playgroud)

constexpr吗?

c++ virtual-functions constexpr c++11

15
推荐指数
3
解决办法
5175
查看次数

在将 constexpr 添加到语言后,将变量声明为 const 是多余的吗?

正如关键字constexpr所暗示的const,它也可以在编译时计算,这是否意味着现在将变量声明为const没有意义,我们应该始终将它们声明为constexpr

c++ constants constexpr c++11

15
推荐指数
3
解决办法
279
查看次数