Constexpr find for array using c++17

守給你的承諾、 提交于 2019-12-04 11:59:47

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

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:

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.

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

— 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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!