Constexpr使用C ++ 17查找数组

编程入门 行业动态 更新时间:2024-10-19 06:15:48
本文介绍了Constexpr使用C ++ 17查找数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试编写constexpr查找函数,该函数将返回包含特定值的std :: array的索引。下面的函数似乎可以正常工作,除非包含的类型为 const char * :

I am trying to write a constexpr find function that will return the index of a std::array containing a certain value. The function below seems to work OK except when the contained type is const char*:

#include <array> constexpr auto name1() { return "name1"; } constexpr auto name2() { return "name2"; } template <class X, class V> constexpr auto find(X& x, V key) { std::size_t i = 0; while(i < x.size()) { if(x[i] == key) return i; ++i; } return i; } int main() { constexpr std::array<const char*, 2> x{{name1(), name2()}}; constexpr auto f1 = find(x, name1()); // this compiles constexpr auto f2 = find(x, name2()); // this doesn't... }

奇怪的是, find(x,name1())可以干净地编译,但 find(x,name2())失败并显示错误:

The weird thing is that find(x, name1()) compiles cleanly but find(x, name2()) fails with the error:

subexpression not valid in a constant expression if(x[i] == key) return i; `

与 name1(),但与 name2()一起使用会失败?

How can this expression work when used with name1() but fail when used with name2()?

我也发现了这个答案,但是用户从头开始构建数组类,我不想这样做。

I have also found this answer, but the user builds the array class from scratch and I do not want to do that.

推荐答案

似乎是编译器错误。 f1 和 f2 应该都无法以相同的方式编译。

Seems like a compiler bug. Both f1 and f2 should fail to compile in the same way.

主要问题是它是一个假设,其中 name1 == name1 和 name1 != name2 。该标准实际上不提供此类保证,请参见 [lex.string] / 16 :

The main issue is that it's an assumption that "name1" == "name1" and "name1" != "name2". The standard in fact provides no such guarantees, see [lex.string]/16:

是否所有字符串文字都是不同的(即存储在非重叠对象中)以及是否连续对 string-literal 产生的对象相同或不同

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified.

即使假设最有可能成立,也要比较 constexpr 明确不允许,请参见 [expr.const] /2.23 :

Even though the assumption most likely holds, comparing unspecified values inside constexpr is expressly not allowed, see [expr.const]/2.23:

—关系( [expr.rel] )或相等( [expr.eq] )运算符,未指定结果;

— a relational ([expr.rel]) or equality ([expr.eq]) operator where the result is unspecified;

一种解决方法(正确的做法)是不依赖字符串文字的地址,而是比较实际的字符串。例如:

A workaround (and the right thing to do) would be to not rely on addresses of string literals and instead compare the actual strings. For example:

constexpr bool equals(const char* a, const char* b) { for (std::size_t i = 0; ; ++i) { if (a[i] != b[i]) return false; if (a[i] == 0) break; } return true; } template <class X, class V> constexpr auto find(X& x, V key) { std::size_t i = 0; while(i < x.size()) { if(equals(x[i], key)) return i; ++i; } return i; }

更多推荐

Constexpr使用C ++ 17查找数组

本文发布于:2023-11-29 20:25:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1647534.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数组   Constexpr

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!