template <class T>
struct is_instantiable
{
static constexpr bool value = /* something */;
}
template <class T>
inline constexpr bool is_instantiable_v = is_instantiable<T>::value;
template <class T> struct is_abstract;
template <class T> struct is_[*]_constructible;
template <class T> struct is_[*]_destructible;
is_[*]_constructible
gives us everything we need, but there are types that have deleted constructors that are nevertheless instantiable:struct instantiable
{
instantiable() = delete;
instantiable(const instantiable&) = delete;
instantiable(instantiable&&) = delete;
instantiable& operator=(const instantiable&) = delete;
instantiable& operator=(instantiable&&) = delete;
int x = 0;
};
//instantiable x0; // not working
instantiable x1{}; // working
From: Vincent Reverdy Sent: Monday, April 9, 2018 1:06 AM To: ISO C++ Standard - Future Proposals Reply To: std-pr...@isocpp.org Subject: [std-proposals] Towards an is_instantiable type trait? |
template <template <class> class Template, class Type>
struct foo
: std::conditional_t<is_inheritable_v<Template<Type>> && is_instantiable_v<Template<Type>>, Template<Type>, std::monostate>
{
// something
};
Hello all,I've been wondering lately whether an is_instantiable type trait would be any useful, and if so why, and how it would be defined. I am pretty neutral on the subject, so this thread is more an exploration of the idea than any concrete proposal. As always constructive feedback is welcome, as well as discussions on ideas.So first, let's define what we are talking about:
template <class T>
struct is_instantiable
{
static constexpr bool value = /* something */;
}
template <class T>
inline constexpr bool is_instantiable_v = is_instantiable<T>::value;Currently the standard has these related traits:
template <class T> struct is_abstract;
template <class T> struct is_[*]_constructible;
template <class T> struct is_[*]_destructible;
I've searched but I am not sure that the standards actually defines what it means that a type can be instantiated even if we (at least "think we") know what it means.
We could think thatis_[*]_constructible
gives us everything we need, but there are types that have deleted constructors that are nevertheless instantiable:
struct instantiable
{
instantiable() = delete;
instantiable(const instantiable&) = delete;
instantiable(instantiable&&) = delete;
instantiable& operator=(const instantiable&) = delete;
instantiable& operator=(instantiable&&) = delete;
int x = 0;
};
//instantiable x0; // not working
instantiable x1{}; // workingSo here are my questions to this group:
- How does the standard defines what it means that a type can be instantiated?
- And if it's not clearly defined, is there anything we could define clearly?
- Or, on the contrary, instantiability is a very blurry notion because of reasons A, B, C (in that case please provide examples why it is a blurry notion)?
- If one can define the notion of instantiability, do the current existing type traits already provide all we need to very easily test if a type is instantiable?
- (I don't think that's the case but I may have missed something)
- If one can define the notion of instantiability and it is not directly covered by existing type traits, how could we implement is_instantiable (ie what should go in the /* something */ of the first code box) (if it's not doable without compiler magic, pseudo-code is welcome)
- So far, none of the three previous questions were discussing the usefulness of such a trait, because definability + implementatibility versus usefulness are completely orthogonal notions. So for the last question let's discuss usefulness: would you have use cases in mind for such a trait?
Thank you very much for your feedback!Best,Vincent
--
Please use another name, instantiation refers to only templates. In fact, every use of "instantiate" in your emails is just wrong.