Reputation: 5415
Suppose I have the following template:
template <typename T> union example {
T t;
constexpr example(const T & t) : t(t) {};
/* We rely on owning class to take care
* of destructing the active member */
~example() {};
};
Because of the destructor there, example<T>
will never be trivially destructible (and thus not, say, a literal type). I'd like to have a partial specialization like
template <typename T> union
example<std::enable_if_t<std::is_trivially_destructible<T>::value, T>> {
T t;
constexpr example(const T & t) : t(t) {};
};
to let example<T>
be trivially destructible when T
is, but unfortunately that gives me the (reasonable, in hindsight) warning
warning: class template partial specialization contains a template parameter that can not be deduced; this partial specialization will never be used
So is there any way to get what I want here?
Upvotes: 4
Views: 727
Reputation: 39101
Maybe with a second, defaulted template parameter?
#include <type_traits>
#include <iostream>
template <typename T, bool = std::is_trivially_destructible<T>::value>
union example {
T t;
constexpr example(const T & t) : t(t) {};
/* We rely on owning class to take care
* of destructing the active member */
~example() { std::cout << "primary template\n"; }
};
template<typename T>
union example<T, true> {
T t;
constexpr example(const T & t) : t(t) {};
};
struct nontrivial
{
~nontrivial() { std::cout << "woot!\n"; }
};
int main()
{
example<nontrivial> e1{{}};
example<int> e2{{}};
}
Upvotes: 6