-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
non-constexpr integral_constant conversions #133
non-constexpr integral_constant conversions #133
Comments
Yes I know :( This was a solution we came up with to avoid type_traits depending on MPL. And indeed it works well, but as you correctly point out the function cannot be I'm open to ideas as at present I don't know how to fix this! |
IIUC, the goal is to allow template<class T, T> struct integral_c;
template<class T, T val>
struct integral_constant {
constexpr operator integral_c<T, val>() const noexcept {
return {};
}
};
constexpr integral_constant<int, 42> i42;
template<class T, T> struct integral_c {};
int main() {
integral_c<int, 42>(i42);
} works, since return types need be complete when instantiating the body, but not the declaration, of a function. I assume that requiring completeness when instantiating the body isn't a huge bar, since presumably the caller wants to actually do something with the returned object. But this seems simple enough that it would have occurred to someone. Is there a requirement I'm missing? |
Nearly: we have tests which rely on dispatching without explicitly including MPL, for example this one https://github.com/boostorg/type_traits/blob/develop/test/mpl_interop_test1.cpp fails with your change. I experimented with:
Which passes all the type_traits tests, but breaks Boost.Test which manages to dereference the returned value, but only with MSVC :( |
If this conversion must be callable when
This is likely a case of MSVC's (Related: I haven't had the opportunity to thank you in person for Boost::Math, which we use to implement the C++17 mathematical special functions in MSVC. Here's a virtual Thank You, which will have to do for now.) |
Indeed: it's legacy really, there was never supposed to be any dependency, but to work around broken compilers (which we no longer support), MPL needed to inject a bunch of code into type_traits. Over time a lot of code came to depend on the traits inheriting from mpl::true_ or mpl::false_ - mostly due to convenience. So... when we removed the no longer needed workarounds, the conversion operators were added to avoid breaking too much other stuff. So... probably the right way to fix this is to stop relying on the conversion in Boost.Math. It's a rather tedious bit of editing, so it may have to wait for a day when I'm really properly bored ;) |
I was looking into the issue a while ago when I was trying to make BOOST_CONSTEXPR operator mpl::integral_c<T, val>() const
{ return mpl::integral_c<T, val>(); }
...
BOOST_CONSTEXPR operator mpl::bool_<val>() const
{ return mpl::bool_<val>(); } works fine on all three major compilers. I do not know if this is actually allowed, DR2335 seems to be about this uncertainty. |
Simplify the dispatching logic to use mpl::if_ and broken compiler workarounds less often. Fixes: boostorg/type_traits#133.
integral_constant
has this conversion operator tompl::integral_c
:which unfortunately is not / cannot be
constexpr
. (Theintegral_constant<bool, meow>
partial specialization has a similar conversion to lvaluempl::bool_<meow>
.) These conversions are used in the initialization of lots of constant data in Boost::math, which could otherwise have constant initialization but sadly currently has dynamic initialization since these conversions are notconstexpr
.Is there any way these could be made
constexpr
conversions to avoid that dynamic initialization?The text was updated successfully, but these errors were encountered: