为什么st_ :: initializer_list <_E> :: size在static_assert中是不允许的,即使它在我的libstdc ++(v.4.6)中被声明为constexpr?
例如,以下代码:
template<class T, int Length>
class Point
{
public:
Point(std::initializer_list<T> init)
{
static_assert(init.size() == Length, "Wrong number of dimensions");
}
};
int main()
{
Point<int, 3> q({1,2,3});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
test.C: In constructor ‘Point<T, Length>::Point(std::initializer_list<_Tp>) [with T = int, int Length = 3]’:
test.C:60:26: instantiated from here
test.C:54:7: error: non-constant condition for static assertion
test.C:54:73: in constexpr expansion of ‘init.std::initializer_list<_E>::size [with _E = int, std::initializer_list<_E>::size_type = long unsigned int]()’
test.C:54:7: error: ‘init’ …Run Code Online (Sandbox Code Playgroud) 我想要一个constexpr从constexpr函数计算的值(即编译时常量).我想要将这两个作用于类的命名空间,即静态方法和类的静态成员.
我第一次写这个(对我来说)明显的方式:
class C1 {
constexpr static int foo(int x) { return x + 1; }
constexpr static int bar = foo(sizeof(int));
};
Run Code Online (Sandbox Code Playgroud)
g++-4.5.3 -std=gnu++0x 对此说:
error: ‘static int C1::foo(int)’ cannot appear in a constant-expression
error: a function call cannot appear in a constant-expression
Run Code Online (Sandbox Code Playgroud)
g++-4.6.3 -std=gnu++0x 抱怨:
error: field initializer is not constant
Run Code Online (Sandbox Code Playgroud)
好吧,我想,也许我必须把事情从课堂上移开.所以我尝试了以下方法:
class C2 {
constexpr static int foo(int x) { return x + 1; }
constexpr static int bar;
}; …Run Code Online (Sandbox Code Playgroud) 为什么此代码会返回警告
警告:ISO C++禁止将字符串常量转换为'char*'[ - WRrite-strings]
如果
在对象声明或非静态成员函数中使用的constexpr说明符(直到C++ 14)暗示const.函数或静态成员变量(自C++ 17)声明中使用的constexpr说明符暗示内联.
#include <cassert>
#include <string>
#include <iostream>
struct A
{
// warning: ISO C++ forbids converting a string constant to ‘char*’
static constexpr char* name_ = "A";
static constexpr char* name() { return name_; };
};
int main()
{};
Run Code Online (Sandbox Code Playgroud)
如果我添加一个const后constexpr,警告消失了:
#include <cassert>
#include <string>
#include <iostream>
struct A
{
static constexpr const char* name_ = "A";
static constexpr const char* name() { return name_; }; …Run Code Online (Sandbox Code Playgroud) Consider
struct A1 {
constexpr A1& operator=(const A1&) = default;
~A1() {}
};
struct A2 {
constexpr A2& operator=(const A2&) = default;
~A2() = default;
};
struct A3 {
~A3() = default;
constexpr A3& operator=(const A3&) = default;
};
Run Code Online (Sandbox Code Playgroud)
GCC and MSVC accept all three structs. Clang rejects A1 and A2 (but accepts A3), with the following error message:
Run Code Online (Sandbox Code Playgroud)<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr constexpr A1& operator=(const A1&) = default; ^ <source>:6:5: error: …
我目前正在创建一个带有constexpr构造函数的类,我想知道是否可以使用a std::array来存储此类的数据.标准是否明确指定a std::array具有constexpr构造函数,并且可以在编译时访问其内容?
考虑这个程序:
template <int F(), int N = F()>
void f() { }
constexpr int g() { return 1; }
int main() { f<g>(); }
Run Code Online (Sandbox Code Playgroud)
这有效吗?编译器是否需要查看模板定义时间,这F可能会引用一个constexpr函数,因此默认参数N可能有效吗?
gcc和clang接受这个,但是Intel 1在模板定义时拒绝模板函数,因为F()它不是一个常量表达式.f<g, g()>()如果默认参数被删除,英特尔确实接受,因此很明显它理解它g()通常可用于常量表达式.
我不清楚标准说的是什么.很明显(C++ 11 [expr.const] p2)
调用除
constexpr文字类或constexpr函数的构造函数之外的函数
呈现一个非常量的表达式,但我不清楚这是否适用于此.在模板定义时,它肯定似乎适用,因为F未声明为constexpr函数,但同时,模板定义时的错误应该仅在模板没有可能的有效实例化时被诊断出来,并且这里似乎确实存在有效的实例化.
我可以看到两个答案的论据,所以我感到困惑.这个问题有明确的答案吗?
1.使用当前版本的英特尔编译器重新测试表明它的工作正常,因此可能是英特尔开发人员认为它是一个错误并且已经修复了它.这是一个巨大的暗示,代码是有效的.尽管如此,根据标准得到一个确定的答案仍然会很好.
为什么没有任何std::algorithm方法constexpr?如果我正确理解新的C++ 14规则,那么很多方法都可以constexpr.例如,为什么不能std::find有constexpr?
static constexpr std::array<char, 4> DnaBases {'A', 'C', 'G', 'T'};
constexpr bool is_dna(char b)
{
return std::find(std::cbegin(DnaBases), std::cend(DnaBases), b) != std::cend(DnaBases); // why not?
}
Run Code Online (Sandbox Code Playgroud)
还有哪些std::algorithm可能constexpr?
我正在尝试使用给定的函数在编译时填充2D数组.这是我的代码:
template<int H, int W>
struct Table
{
int data[H][W];
//std::array<std::array<int, H>, W> data; // This does not work
constexpr Table() : data{}
{
for (int i = 0; i < H; ++i)
for (int j = 0; j < W; ++j)
data[i][j] = i * 10 + j; // This does not work with std::array
}
};
constexpr Table<3, 5> table; // I have table.data properly populated at compile time
Run Code Online (Sandbox Code Playgroud)
它运行得很好,table.data在编译时正确填充.
然而,如果我改变普通2D阵列int[H][W]与std::array<std::array<int, H>, W> …
我正在尝试使用 C++17if constexpr进行条件编译,但它的行为并不符合我的预期。
比如下面的代码,C++还是编译宏定义的代码X2,
#include <map>
#include <string>
#include <iostream>
#include <type_traits>
#define X1 pp("x")
#define X2 pp("x", "x")
void pp(const std::string str)
{
std::cout << str << std::endl;
}
int main()
{
std::map<std::string, int> map;
if constexpr (std::is_null_pointer_v<decltype(map)>)
X2;
else
X1;
}
Run Code Online (Sandbox Code Playgroud)
并吐出此错误消息:
#include <map>
#include <string>
#include <iostream>
#include <type_traits>
#define X1 pp("x")
#define X2 pp("x", "x")
void pp(const std::string str)
{
std::cout << str << std::endl;
}
int main()
{
std::map<std::string, int> map; …Run Code Online (Sandbox Code Playgroud) 显然,constexpr std::string尚未添加到GCC的libstdc++中(从 GCC v11.2 开始)。
这段代码:
#include <iostream>
#include <string>
int main()
{
constexpr std::string str { "Where is the constexpr std::string support?"};
std::cout << str << '\n';
}
Run Code Online (Sandbox Code Playgroud)
不编译:
#include <iostream>
#include <string>
int main()
{
constexpr std::string str { "Where is the constexpr std::string support?"};
std::cout << str << '\n';
}
Run Code Online (Sandbox Code Playgroud)
char当字符串包含超过 16秒(因为 GCC 的 SSO 缓冲区大小为 16)时,此类字符串将如何工作?简短的解释是什么?一个简单的构造函数会在堆栈上创建字符串对象并且从不使用动态分配吗?
这段代码:
std::cout << "is_trivially_constructible: "
<< std::boolalpha << std::is_trivially_constructible<const std::string>::value << '\n'; …Run Code Online (Sandbox Code Playgroud)