标题说明了所有这两种常用方法都不起作用.我错过了什么?
1.
class Cl {
static constexpr double PI;
};
constexpr double Cl::PI = 3.14;
Run Code Online (Sandbox Code Playgroud)
(26):错误C2737:'private:static double const Cl :: PI':'constexpr'对象必须初始化
2.
class Cl {
static constexpr double PI = 3.14;
};
Run Code Online (Sandbox Code Playgroud)
(26):错误C2864:'Cl :: PI':具有类内初始化程序的静态数据成员必须具有非易失性const整数类型
类型为'const double'
在两次尝试中,错误都在类中的同一行.我正在使用VisualStudio/MSVC 2013年11月CTP编译器.
请注意,使变量const不是解决方案,因为我想在constexpr函数和普通函数中使用此常量.
我以下列方式宣布了一堂课
class A
{
struct B
{
constexpr
B(uint8_t _a, uint8_t _b) :
a(_a),
b(_b)
{}
bool operator==(const B& rhs) const
{
if((a == rhs.a)&&
(b == rhs.b))
{
return true;
}
return false;
}
uint8_t a;
uint8_t b;
};
constexpr static B b {B(0x00, 0x00)};
};
Run Code Online (Sandbox Code Playgroud)
但是g ++说
错误:字段初始值设定项不是常量
无法弄清楚我错在哪里.
将不胜感激任何帮助!
谢谢和reagards!
我有以下代码:
main.cpp中
#include <cstdint>
#include <type_traits>
enum class FooEnum : uint8_t{
Foo1 = 0,
Foo2 = 1
};
constexpr uint32_t& operator|= (uint32_t& lhs, FooEnum rhs) {
return lhs |= 1u << static_cast<uint8_t>(rhs);
}
int main() {
uint32_t bar{0};
bar|=FooEnum::Foo1;
}
Run Code Online (Sandbox Code Playgroud)
基本上,|=运算符应该采用枚举并设置位,其位置对应于其整数值.
在fedora 21上用clang ++ 3.5.0编译时,一切正常,但是当用g ++ 4.9.2编译时,它会抛出一个错误,说这不是一个常量表达式:
main.cpp: In function ‘constexpr uint32_t& operator|=(uint32_t&, FooEnum)’:
main.cpp:16:2: error: expression ‘(lhs = (lhs | (1u << ((int)rhs))))’ is not a constant-expression
}
^
Run Code Online (Sandbox Code Playgroud)
对于所有类型的编译器标志组合都是如此,但是你可以测试它g++ -std=c++11 -o …
例如,除非incr()声明,否则下面的代码不会编译constexpr:
int incr(int& n) {
return ++n;
}
constexpr int foo() {
int n = 0;
incr(n);
return n;
}
Run Code Online (Sandbox Code Playgroud)
看看C++ 14中的§7.1.5/ 3,我们有:
constexpr函数的定义应满足以下约束条件:
(3.1) - 它不应是虚拟的(10.3);
(3.2) - 其返回类型应为字面类型;
(3.3) - 每个参数类型应为文字类型;
(3.4) - 其函数体应为= delete,= default或不包含的复合语句(3.4.1) - asm-definition,
(3.4.2) - goto语句,
(3.4.3) - try-block,或
(3.4.4) - 非文字类型的变量的定义或静态或线程存储持续时间或未执行初始化的时间.
struct rgb_color {
constexpr rgb_color(std::uint8_t nr, std::uint8_t ng, std::uint8_t nb) :
r(nr), g(ng), b(nb) { }
std::uint8_t r; // red
std::uint8_t g; // green
std::uint8_t b; // blue
constexpr static rgb_color black = rgb_color(0, 0, 0);
constexpr static rgb_color white = rgb_color(255, 255, 255);
};
Run Code Online (Sandbox Code Playgroud)
该constexpr static常量定义无法编译:
constexpr variable cannot have non-literal type 'const rgb_color'
Run Code Online (Sandbox Code Playgroud)
但是根据http://en.cppreference.com/w/cpp/concept/LiteralType,const rgb_color应该是文字类型,因为它只有文字类型作为数据成员(std::uint8_t)和constexpr构造函数.
为什么代码不能编译?
此外,是否有必要constexpr static在.cc文件中定义成员,如
constexpr rgb_color rgb_color::black;
Run Code Online (Sandbox Code Playgroud) 前几天我正在阅读C++文档,并注意到虽然文字类型不能有虚拟成员,但这并不妨碍它们实现虚拟成员.或者至少这是我所理解的.
这是我一直在玩的一些代码:
#include <cassert>
// Some forward declarations:
enum class literal_id;
struct literal_base;
struct literal_a;
struct literal_b;
// Now some definitions:
enum class literal_id {
a, b
};
struct literal_base {
virtual literal_id method() const noexcept = 0;
};
struct literal_a : public literal_base {
constexpr literal_id method() const noexcept final { return literal_id::a; }
constexpr operator literal_b() const noexcept;
};
struct literal_b : public literal_base {
constexpr literal_id method() const noexcept final { return literal_id::b; }
constexpr …Run Code Online (Sandbox Code Playgroud) 我想要一个static constexpr模板化类中的类元素数组,类似于以下代码:
struct Element {
unsigned i;
constexpr Element (unsigned i) : i(i) { }
};
template <bool Reverse>
struct Template {
static constexpr Element element[] = {
Element (Reverse ? 1 : 0),
Element (Reverse ? 0 : 1),
};
};
int main (int argc, char **argv) {
return Template<true>::element[0].i;
}
Run Code Online (Sandbox Code Playgroud)
当然,实际Element结构比这个例子更复杂,但它已经显示出问题.如果我编译这个机智gcc我得到一个关于递归依赖的错误:
test.cc: In instantiation of ‘constexpr Element Template<true>::element [2]’:
test.cc:11:27: recursively required from ‘constexpr Element Template<true>::element [2]’
test.cc:11:27: required from ‘constexpr Element …Run Code Online (Sandbox Code Playgroud) 尝试在特定类类型上为该类的特定构造函数设置make_shared别名.我最好的尝试:
class foo { public: foo(int x) : y(x) {} int y; };
constexpr auto newfoo = static_cast<std::shared_ptr<foo>(*)(int)>(std::make_shared<foo>);
Run Code Online (Sandbox Code Playgroud)
产量:
error: invalid static_cast from type ‘<unresolved overloaded function type>’ to type ‘std::shared_ptr<foo> (*)(int)’
constexpr auto newfoo = static_cast<std::shared_ptr<foo>(*)(int)>(std::make_shared<foo>);
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我有以下第三方API:
using StatisticsFunc = double (*)(const std::vector<double> &)
libraryClass::ComputeStatistics(StatisticsFunc sf);
Run Code Online (Sandbox Code Playgroud)
我正在使用这样的:
obj1->ComputeStatistics([](const auto& v) {return histogram("obj1", v);};
obj2->ComputeStatistics([](const auto& v) {return histogram("obj2", v);};
Run Code Online (Sandbox Code Playgroud)
但所有这些lambdas只是重复代码.我宁愿这样:
obj1->ComputeStatistics(getHistogramLambda("obj1"));
Run Code Online (Sandbox Code Playgroud)
所以我需要定义:
constexpr auto getHistogramLambda(const char* name) {
return [](const auto& v) {return histogram(name, v);};
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为name没有被捕获.这也不会起作用:
constexpr auto getHistogramLambda(const char* name) {
return [name](const auto& v) {return histogram(name, v);};
}
Run Code Online (Sandbox Code Playgroud)
因为捕获lambda不再是无状态的,不能转换为函数指针.
Ofc可以将其作为宏来实现,但我想要一个现代的C++ 17解决方案.
传递字符串作为模板参数似乎也是一个选项:https:
//stackoverflow.com/a/28209546/7432927,但我很好奇是否有constexpr办法做到这一点.
考虑以下代码:
#include <cstdint>
static int x = 0;
const uintptr_t arithmetic()
{
static constexpr uintptr_t result = ((uintptr_t)&x) + 1u;
return result;
}
const uintptr_t bitwise()
{
static constexpr uintptr_t result = ((uintptr_t)&x) | 1u;
return result;
}
Run Code Online (Sandbox Code Playgroud)
GCC(所有版本4-9)都arithmetic()可以正常编译,但可以拒绝bitwise():
<source>: In function 'const uintptr_t bitwise()':
<source>:13:57: error: '(((uintptr_t)(& x)) | 1)' is not a constant expression
13 | static constexpr uintptr_t result = ((uintptr_t)&x) | 1u;
| ~~~~~~~~~~~~~~~~^~~~
Run Code Online (Sandbox Code Playgroud)
为什么?请注意,在其他constexpr用例中,按位-或工作正常,但不是这种情况。