Question

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?

Was it helpful?

Solution

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{{}};
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top