我一直在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++ 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)
非常感谢你.
请考虑以下代码:
#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它是非文字的.
为什么空的析构函数和没有析构函数之间有什么区别呢?
编辑:另一个相关的问题:如果空和文字析构函数不同如何定义受保护的文字析构函数?
通常,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) 这是本主题的某种后续行动,涉及其中的一小部分.与前一个主题一样,让我们考虑一下我们的编译器有和的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) 给出以下代码:
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必然使用的ODR的int a = A::a[0]?
注意:这个问题代表了休息室辩论的一个不那么闷热/不合逻辑/无穷无尽的版本.
在<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?
我想要一个编译时字符串加密,这样我就可以在我的代码中编写:
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的支持.
有什么建议?
我已经研究过编译时字符串加密,它没有为问题提供constexpr解决方案.
我还研究了http://www.unknowncheats.me/forum/c-and-c/113715-compile-time-string-encryption.html.虽然它是一个constexpr解决方案,但VS2015仍然将字符串纯文本添加到二进制文件中.
可以X::f()在下面的代码中使用虚函数
struct X
{
constexpr virtual int f() const
{
return 0;
}
};
Run Code Online (Sandbox Code Playgroud)
是constexpr吗?
正如关键字constexpr所暗示的const,它也可以在编译时计算,这是否意味着现在将变量声明为const没有意义,我们应该始终将它们声明为constexpr?
c++ ×10
c++11 ×10
constexpr ×10
assert ×1
c++14 ×1
compile-time ×1
constants ×1
destructor ×1
inline ×1