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