我想用constexpr char[]另一个constexpr char []成员初始化成员。可以在上面C++11或者上面做吗?
#include <iostream>
struct Base {
static constexpr char ValueOne[] = "One";
static constexpr char ValueTwo[] = "Two";
};
template <typename T>
struct ValueOneHolder {
static constexpr char Value[] = T::ValueOne; // << How can one initialize this?
};
int main() {
std::cout << ValueOneHolder<Base>::Value << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 有没有办法在 Qt 中定义静态 constexpr 字符串文字成员?即类似以下内容:
class X
{
static constexpr QString tag = "mytag";
};
Run Code Online (Sandbox Code Playgroud) 我正在尝试初始化一个多维数组,虽然可以在启动时填充该数组一次,但我真的更喜欢该数组constexpr,所以我想知道是否有一种方法可以让编译器为我执行此操作,特别是因为我可以提供一个 constexpr 函数,该函数接受每个索引的参数并返回数组应位于索引处的值。
例如:
constexpr bool test_values[64][64][64][64] = {
... // magic goes here
};
Run Code Online (Sandbox Code Playgroud)
我有一个函数constexpr bool f(int,int,int,int)可以告诉我每个元素应该是什么。我更喜欢通过数组访问条目,因为进行数组查找比调用 f() 获取非常量值更快。
我发现的大多数与在运行时初始化数组相关的其他问题都使用 std::array 而不是 C 数组,而且我找不到的问题都是多维的。我曾尝试将多维数组展开为一维数组,并使用 std::array 方法,例如我在这个问题的答案之一中找到的方法,但我发现 gcc 9.1 生成的结果代码仍然填充了数组在启动时一次,而不是编译器直接生成数组。
我可以做些什么来让编译器填充这种数组,还是我必须保留test_values有效的非constexpr,并在运行时初始化一次?
编辑:
澄清一下,我本质上并不反对使用 std::array 而不是内置的 C 风格数组,但我不认为 std::arrays 对多维特别友好,并且使用一维数组会混淆我的内容程序需要做的事情(坦率地说,如果必须的话,我愿意将其实现为一维 std::array ,但是多维数组感觉比手动展开的同等大小的一维数组更容易混淆,这就是为什么我用多维 C 数组来描述它)。
在函数体内使用static constexpr和时有什么区别吗?constexpr
int SomeClass::get(const bool b)
{
static constexpr int SOME_CONSTANT = 3;
constexpr int SOME_OTHER_CONSTANT = 5;
if(b)
return SOME_CONSTANT;
else
return SOME_OTHER_CONSTANT;
}
Run Code Online (Sandbox Code Playgroud) 考虑以下程序。它只是将 a 复制constexpr const char *到 a static const char *。我希望指针被复制,并且是相同的。这就是 gcc、clang 和 msvc 的大多数选项都会发生的情况。
但是,当使用 flag/Zi标志而不是/ZI最近的 msvc 时,会触发断言。我想知道这是编译器错误还是只是未定义的行为。
#include <cassert>
constexpr const char *test = "test";
int main()
{
static const char *a = test;
assert(a == test);
}
Run Code Online (Sandbox Code Playgroud)
这是编译器资源管理器链接:https://godbolt.org/z/WPz7GPosa。只需在执行程序选项卡中更改/Zi为即可/ZI使断言消失。
谢谢!
我的问题是为什么以下代码是有效的 C++:
#include <iostream>
#include <tuple>
#include <type_traits>
std::tuple<const char *, const char *> tuple("Hello", "world");
std::integral_constant<std::size_t, 0> zero;
std::integral_constant<std::size_t, 1> one;
template<typename T> const char *
lookup(T n)
{
// I would expect to have to write this:
// return std::get<decltype(n)::value>(tuple);
// But actually this works:
return std::get<n>(tuple);
}
int
main()
{
std::cout << lookup(zero) << " " << lookup(one) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
当然,我很高兴能够以这种方式编程。而且,我知道std::integral_constant有一个constexpr转换运算符。但是,参数ntolookup不是 constexpr,因此我对非 constexpr 对象上的非静态方法(即使方法本身是 constexpr)如何可能返回编译时常量感到困惑。
当然,在这种情况下我们碰巧知道转换运算符的主体不查看运行时值,但类型签名中没有任何内容保证这一点。例如,以下类型显然不起作用,尽管它也有 constexpr 转换运算符: …
我试图在编译时确定所有传递对象的大小,然后在超过最大大小时通过 static_assert 中止构建过程。
#include <iostream>
template<class T>
class Test
{
public:
T value;
constexpr size_t size() const { return sizeof(T) + 3; }
};
template<typename ...T>
constexpr int calc(const T&...args)
{
return (args.size() + ...);
}
template<typename ...T>
void wrapper(const T& ...args)
{
// error: 'args#0' is not a constant expression
constexpr int v = calc(args...);
static_assert(v <= 11, "oops");
}
int main()
{
Test<int> a;
Test<char> b;
// a.size() + b.size() == 11
// works
constexpr int v = …Run Code Online (Sandbox Code Playgroud) 假设我有一个constexpr变量,其中包含所有小于 2 16的素数。
constexpr auto primes = [] {
constexpr int N = 1 << 16;
std::array<int, 6542> ret;
bool not_prime[N] = {};
int prime_cnt = 0;
for (int i = 2; i < N; i++) {
if (!not_prime[i]) {
ret[prime_cnt++] = i;
for (int j = 2 * i; j < N; j += i) not_prime[j] = true;
}
}
return ret;
}();
Run Code Online (Sandbox Code Playgroud)
这里我手动指定了 的ret数组大小。当我想要更改时N,我必须重新运行此循环以查看最终prime_cnt值是什么并手动指定它。特别是,如果我增加N,我必须首先给出一个上限猜测以避免段错误。
在C++20中,我们可以在编译时动态分配内存,因此我们constexpr现在有了向量。所以我们不再需要担心上限问题。但这样的值不能在运行时使用,这意味着这段代码是无效的。 …
有没有办法编写一个 constexpr 函数来返回 std::vector 的嵌套深度?
例子:
get_vector_nested_layer_count<std::vector<std::vector<int>>>() // 2
get_vector_nested_layer_count<std::vector<std::vector<std::vector<float>>>>() // 3
Run Code Online (Sandbox Code Playgroud) 我尝试让成员函数要求静态 constexpr 布尔成员为 true。这对于 DRY 一个相当复杂的需求非常有帮助。我不知道编译器不允许我这样做的原因。
要求稍微不那么复杂的最小示例:
template <typename T>
struct Foo
{
static constexpr bool isInt = std::integral<T>;
void bar() requires (isInt);
void goo() requires std::integral<T>;
};
template <typename T>
void Foo<T>::bar() requires (Foo<T>::isInt) // error: out-of-line definition of 'bar' does not match any declaration in 'Foo<T>' x86-64 clang 14.0.0 #1
{
// ...
}
template <typename T>
void Foo<T>::goo() requires std::integral<T> // ok
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
这是因为isInt是在同一个类中声明的吗?或者我有某种语法错误?