constexpr operator==(variant, variant)
Jonathan Wakely
jwakely@redhat.com
Tue Nov 22 13:38:00 GMT 2016
On 22/11/16 00:03 -0800, Tim Shen wrote:
>Hi,
>
>I realized that operator== on variant is required to be constexpr by
>p0088r3, which is not the case in our implementation (it's probably my
>oversight).
>
>Currently, operator== is implemented in terms of an array of function pointers:
> static constexpr Func_ptr vtable[] = { &handle_types<Types...> };
> return vtable[v1.index()](v1.raw_storage(), v2.raw_storage());
>
>When v1.index() == v2.index(). The problem with this approach is that,
>in handle_types we have to cast the input parameters as void* to T*,
>which isn't allowed in constexpr functions.
>
>If we take another approach, that is constructing an if-else chain
>using meta-programming:
> if (v1.index() == 0) { return get<0>(v1) == get<0>(v2); } else
> if (v1.index() == 1) { return get<1>(v1) == get<1>(v2); } else
> ...
>
>This satisfies constexpr requirements. However, GCC generates
>inefficient code for if-else chain: https://godbolt.org/g/AEYMwC
>Although Clang generates perfect local jump tables.
>
>My question is: what do we do now? I tend to leave it as is (not
>constexpr) until GCC catches up, then we switch to the if-else chain
>solution.
We should at least report a missed-optimization bug.
My preference would be to make the function constexpr, with reduced
performance. I don't know how critical the performance of comparing
variants is, and we're not claiming our C++17 features are optimial
yet anyway.
More information about the Libstdc++
mailing list