Let me begin by noting a very similar question: Detecting constexpr using SFINAE . The difference is that in this question the discovery method works to detect the static class method.
I am trying to determine if a copy of constexpr can be constructed. I'm pretty close, here is what I have:
template <class T> constexpr int return_int(T t) { return 0; } template <class T> T& unmove(T&& t) { return t; } template <class ... T> using void_t = void; template <class T, class = void> struct is_constexpr_copy_constructible : std::false_type {}; template <class T> struct is_constexpr_copy_constructible<T, void_t< std::integral_constant<int, return_int(unmove(T{})) > >> : std::true_type {};
The logical promotion of ideas in this solution is as follows:
- For integer template parameters, only constant expressions can be used.
- The result of calling the function is considered only as constexpr if the function constexpr and all its parameters are constexpr.
- Passing something by value will produce a copy.
So, I am writing a return_int function that gives me a constexpr integer if a constexpr expression of a type having an instance constructor constexpr is passed. unmove simply ensures that the copy constructor is called, not the move constructor.
The problem is that in order to get the expression in the first place, I have to create my type. I cannot use declval for this, as would be standard in TMP, because this is not an invaluable context; return_int will actually be evaluated at compile time to calculate the type. So I'm stuck in a meta function that determines whether the constexpr copy type is constructive and constexpr is constructive by default.
This is not the end of the world as such, as these things tend to intersect, but it is not ideal. Is there any way around this? It basically boils down to:
- I see no way to check if something is constexpr in an invaluable context.
- In the evaluated context, I see no way to get an instance of the type that I am testing to try to make a copy without calling the constructor.
Please note that in a similar question that I linked, this is simply not a problem, because it checks the static methods and therefore just does not need an instance.
reference
source share