constexpr 相关问题

constexpr是C ++ 11中引入的修饰符,它通知编译器函数或变量的值是已知的,或者可以在编译时计算。因此,它可以在不可能的地方用作常数。

在同一类中使用 constexpr 作为模板参数时出错[重复]

如果我尝试编译以下 C++0x 代码,则会收到错误: 模板 struct foo { }; 结构栏{ 静态 constexpr int number() { return 256; } 无效函数(foo 如果我尝试编译以下 C++0x 代码,则会收到错误: template<int n> struct foo { }; struct bar { static constexpr int number() { return 256; } void function(foo<number()> &); }; 使用gcc 4.6.1,错误消息是: test.cc:6:27: error: ‘static constexpr int bar::number()’ used before its definition test.cc:6:28: note: in template argument for type ‘int’ 使用 clang 2.8,错误消息是: test.cc:6:20: error: non-type template argument of type 'int' is not an integral constant expression void function(foo<number()> &); ^~~~~~~~ 1 error generated. 如果我将 constexpr 函数移至基类,它可以在 gcc 上运行,并在 clang 上给出相同的错误消息: template<int n> struct foo { }; struct base { static constexpr int number() { return 256; } }; struct bar : base { void function(foo<number()> &); }; 代码是否错误,或者是 gcc 4.6 对 C++0x 实现的限制或错误?如果代码是错误的,为什么是错误的,C++11标准的哪些条款说它是错误的? 在 C++ 中,类的成员函数的内联定义仅在解析类中的每个声明后才会解析。因此,在第一个示例中,编译器在声明 number() 时看不到 function() 的定义。 (没有发布的 clang 版本支持评估 constexpr 函数,因此您的任何测试用例都无法在那里工作。) 这将编译成功: struct Sub{constexpr Sub(int i){}}; struct Test{ static constexpr Sub s=0; };

回答 2 投票 0

constexpr 组合评估失败

我尝试使用 constexpr 并尝试将 ipv4 地址解析为四位数字,但它不起作用。所以我将代码精简到失败的地方: #包括 #包括 我尝试使用 constexpr 并尝试将 ipv4 地址解析为四位数字,但它不起作用。所以我将代码精简到失败的程度: #include <cstdint> #include <stdexcept> #include <string_view> #define WORKS 1 static constexpr uint8_t getIpVal(const std::string_view &sv) noexcept { size_t pos = 0; auto len = sv.size(); unsigned long val = 0; while (sv[pos] >= '0' && sv[pos] <= '9' && pos < len) { int digit = sv[pos] - '0'; val *= 10; val += digit; if (val > UINT8_MAX) { return 0; // throw std::invalid_argument(sv.data()); } ++pos; } if (pos < len) { return 0; // throw std::invalid_argument(sv.data()); } return val; } static constexpr auto operator""_ipv4(const char *ipv4Ptr, const size_t size) { const std::string_view ipv4Str(ipv4Ptr, size); const auto pos1 = ipv4Str.find('.'); if (pos1 == std::string_view::npos) { throw std::invalid_argument(ipv4Ptr); } const auto str1 = ipv4Str.substr(0, pos1); #if WORKS return str1; #else return getIpVal(str1); #endif } auto test1() { return "127.0.0.1"_ipv4; } auto test2() { return getIpVal("127"); } 我正在尝试使用编译器资源管理器来编译它:https://godbolt.org/z/aY3ETo6ba 只要将 WORKS 定义为 1,一切似乎都工作正常: .LC0: .string "127.0.0.1" test1(): mov eax, 3 mov edx, OFFSET FLAT:.LC0 ret test2(): mov eax, 127 ret 但是如果我将其设置为零,编译器将创建一个完整的代码,其中包含一个循环来计算该数字。我不懂为什么。 单个功能似乎有效,但组合起来却失败了。在我看来,它应该只创建两个带有数字的函数: test1(): mov eax, 127 ret test2(): mov eax, 127 ret 您的缓冲区溢出了。您在调用string_view::operator[]后检查索引是否太大: while (sv[pos] >= '0' && sv[pos] <= '9' && pos < len) // Fixed: while (pos < len && sv[pos] >= '0' && sv[pos] <= '9')

回答 1 投票 0

constexpr指针如何存在并且constevel函数在编译时返回指针?

我正在浏览 constexpr 和 consteval 的主题,发现以下内容, 我们可以拥有 CONSTEXPR 类型的指针 CONSTEVAL 函数可以返回 CONSTEXPR 变量的指针 一个...

回答 1 投票 0

constexpt指针如何存在并且constevel函数在编译时返回指针?

我正在浏览 constexpr 和 consteval 的主题,发现以下内容, 我们可以拥有 CONSTEXPR 类型的指针 CONSTEVAL 函数可以返回 CONSTEXPR 变量的指针 一个...

回答 1 投票 0

使用局部变量的引用来初始化 constexpr 变量是否有效?

以下代码只能在 GCC 上编译(在 godbolt.org 上检查了 10.4 和 13.2),但不能在 Clang 上编译(在我尝试过的所有版本上都失败,例如 godbolt.org 上的 17.1): 结构体A { 静态常量表达式...

回答 1 投票 0

初始化结构体中的静态 constexpr 变量和类

这是我的工作代码示例: #包括 模板 B类{ 民众: 整数y; constexpr b(int x) : y(x) { } constexpr void sayhi() { 标准::

回答 2 投票 0

在 C++14 中初始化 std::array 类型的静态 constexpr 成员

我无法以编程方式初始化静态 constexpr std::array 成员。 这是我的问题的一个最小示例(因为简化尺寸已知并且很小,因此初始化可以是手动的......

回答 1 投票 0

c++ 将 std::source_location::function_name() 作为字符串文字模板参数传递

我有这段代码,它返回编译时由 __PRETTY_FUNCTION__ 宏提供的修改后的函数名称字符串: 模板 结构体SL { 字符值[N]; constexpr SL(const ch...

回答 1 投票 0

consteval:调用 consteval 函数 'encrypt_string' 不是常量表达式,指向临时子对象的指针不是常量表达式

我想使用 consteval 关键字在 C++ 中创建一个简单的字符串加密。以前,我使用 constexpr,它可以工作,但某些字符串在运行时被加密。所以,我决定改用

回答 1 投票 0

如何使用C++模块:带模板的私有片段?

我正在尝试 C++20,以更好地了解它们在实践中的工作原理。我了解了模块:私有片段,可用于将接口与实现分开,而 k...

回答 2 投票 0

C++11:用另一个 constexpr char 数组初始化 constexpr char 数组

我想用另一个 constexpr char [] 成员初始化 constexpr char[] 成员。可以用C++11或以上版本实现吗? #包括 结构基{ static constexpr char Va...

回答 2 投票 0

如何初始化 std::pair 的 constexpr std::array <int, const char[]>?

在 C++14 中,如何初始化包含文本字符串的 std::pair 的全局 constexpr std::array?以下不起作用: #包括 constexpr std::array 在 C++14 中,如何初始化包含文本字符串的 std::array 的全局 constexpr std::pair?以下不起作用: #include <array> constexpr std::array<std::pair<int, const char[]>, 3> strings = { {0, "Int"}, {1, "Float"}, {2, "Bool"}}; 你就快到了。首先,char const[]类型需要是一个指针,因为它是一个不完整的类型,可能无法保存在std::pair中。其次,你缺少一对牙套。正确的声明将如下所示: constexpr std::array<std::pair<int, const char*>, 3> strings = {{ {0, "Int"}, {1, "Float"}, {2, "Bool"}, }}; 需要额外的大括号,因为 std::array 是保存原始 C 数组的聚合,因此我们需要显式提到的大括号,以便 {0, "Int"} 不会被错误地视为内部数组对象的初始化程序。 C++20 中的另一种选择是使用 std::to_array,它允许您创建一个不需要预先指定大小的数组。 constexpr auto strings = std::to_array<std::pair<int, const char*>>({ {0, "Int"}, {1, "Float"}, {2, "Bool"}, });

回答 2 投票 0

c++ constexpr 以及为什么我们使用常量表达式

下面只是一个简单的程序来演示constexpr关键字的用法,这个关键字在涉及constexpr时经常使用。为什么我们要把它写得很长,而不只是把输出数字......

回答 1 投票 0

为什么 constexpr 局部变量的地址不是常量表达式?

以下 constexpr 函数无法编译: constexpr 无效 fnc() { constexpr int i = 5; constexpr 自动 ptr = &i; } 考虑到所有评估,为什么 ptr 不能为 constexpr

回答 1 投票 0

通过 lambda 初始化 constexpr 变量

#包括 #包括 constexpr auto fx = [] (std::string msg) { 返回消息+“! ”; }; int main(int argc, char* argv[]) { if (argc == 2) std::cout << "h...

回答 1 投票 0

为什么不能声明 constexpr 非静态数据成员?

尝试创建具有 constexpr 属性的结构成员而不是静态会导致编译器错误(见下文)。这是为什么?对于单个常量值,我会将这个值存储在内存中...

回答 1 投票 0

为什么这个 constexpr 静态成员函数在调用时不被视为 constexpr?

为什么这个constexpr静态成员函数,由//!标识不,评论,调用时没有被视为 constexpr? 结构 Item_id { 枚举 枚举 { 大小、位置、属性、window_...

回答 2 投票 0

不能使用嵌套类的constexpr函数

结构Foo { 结构栏 { 整数数据=0; //constexpr Bar() = 默认; // 也不起作用 constexpr Bar() : 数据(0) {} }; static constexpr Bar bar = {}; //

回答 2 投票 0

C++ - 无法使用嵌套类的 constexpr 函数

结构Foo { 结构栏 { 整数数据=0; //constexpr Bar() = 默认; // 也不起作用 constexpr Bar() : 数据(0) {} }; static constexpr Bar bar = {}; //

回答 1 投票 0

如何检查模板参数是否是2的幂?

我想创建一个静态分配 2^N 字节数组的结构,但我不希望该结构的用户指定这个大小作为指数。例子: 我的愚蠢数组 我想创建一个静态分配 2^N 字节数组的结构,但我不希望该结构的用户指定此大小作为指数。示例: my_stupid_array<char, 32> a1; // I want this! my_stupid_array<char, 5> a2; // And not this... 如何检查此模板参数是否为 2 的幂并通过一条不错的消息警告用户? 我已经能够使用一个简单的模板来检查这一点: template<int N> struct is_power_of_two { enum {val = (N >= 1) & !(N & (N - 1))}; }; 但是,我无法用理智的消息警告用户这一点。有什么想法吗? 编辑 修复了不明确的示例。 编辑 1确实是2的幂。解决了这个问题! :) 编辑 使用 BOOST_STATIC_ASSERT,我在使用 GCC 时收到此代码的编译错误: template<int N> struct is_power_of_two { enum {val = (N >= 1) & !(N & (N - 1))}; BOOST_STATIC_ASSERT(val); }; 错误 ..\main.cpp:29:1: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>' http://ideone.com/cMfEf 编辑 哦,我明白了。这是断言失败时我应该收到的消息。但这未能给用户一些理智的信息。 :( 这些天,有了 constexpr 和 一些小小的技巧,你就可以 constexpr bool is_powerof2(int v) { return v && ((v & (v - 1)) == 0); } static_assert 来救援(仅限 C++11,对于 C++03 取消注释 BOOST_STATIC_ASSERT): #include<iostream> // #include <boost/static_assert.hpp> template<int N> struct is_power_of_two { enum {val = N && !(N & (N - 1))}; static_assert(val, "should use a power of 2 as template parameter"); // BOOST_STATIC_ASSERT(val); // without C++11 support, won't take a string message }; int main() { std::cout << is_power_of_two<2>::val << "\n"; std::cout << is_power_of_two<3>::val << "\n"; } C++11 的 Ideone 输出 C++03 的 Ideone 输出 更新1:其他想法(我知道你不想要这个,但对于大指数来说要容易得多): template<int N> make_power_of_two { enum { val = 1 << N }; }; my_stupid_array<char, make_power_of_two<5>::val > a1; // size 2^5 = 32 更新2:根据@sehe在聊天中的评论,您也可以对constexpr功能执行此操作 constexpr bool is_power_of_two(int x) { return x && ((x & (x-1)) == 0); } 您可以使用 static_assert 提供错误消息: template<int N> struct is_power_of_two { static_assert((N > 1) & !(N & (N - 1)), "Template parameter must be a power of two."); }; 我知道这是一个老问题,但我想根据上面的答案(谢谢你顺便说一句!)提出我刚刚使用的另一个选项以及 c++20 概念: template<auto V> constexpr bool is_power_of_two = V && ((V & (V - 1)) == 0); template<class T, auto SIZE> requires is_power_of_two<SIZE> using my_stupid_array = std::array<T, SIZE>; my_stupid_array<char, 32> a1; // FINE my_stupid_array<char, 5> a1; // COMPILER ERROR

回答 4 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.