On Mon, 20 Feb 2017 22:01:26 +0000
Chris Vine <chris@cvine--nospam--.
freeserve.co.uk> wrote:
> On Mon, 20 Feb 2017 09:45:52 -0500
> bitrex <
bit...@de.lete.earthlink.net> wrote:
> > How do I use std::enable_if and std::is_trivially_copyable to enable
> > or disable a constructor depending on whether the underlying
> > class's template parameter is trivially copyable, or not?
> >
> > I found this article:
> >
> >
http://seanmiddleditch.com/using-stdenable_if-on-constructors/
> >
> > but I admit I don't completely understand what's going on here or
> > how to apply it to my situation.
>
> It depends on what other constructors there are, but in C++14
> something like this will work:
[snip]
It occurs to me on rereading this that what you may be trying to do is
to select the constructor based not on the argument passed to the
constructor (which is what my previous examples did) but on the template
type of the class itself. That is more complicated - to use std::enable_if
for this you need a combination of SFINAE with partial specialization.
This will do that for you:
#include <iostream>
#include <type_traits>
#include <string>
template <class T, class = void>
struct MyClass {
MyClass()
{std::cout << "In non-trivially copiable constructor\n";}
};
template <class T>
struct MyClass<T, std::enable_if_t<std::is_trivially_copyable<T>::value>> {
MyClass()
{std::cout << "In trivially copiable constructor\n";}
};
int main () {
MyClass<int> m1;
MyClass<std::string> m2;
}
However, in this usage I would be inclined to ignore SFINAE and std::enable_if
completely and use a template alias instead:
template <class T, bool>
struct MyClassImpl {
MyClassImpl()
{std::cout << "In non-trivially copiable constructor\n";}
};
template <class T>
struct MyClassImpl<T, true> {
MyClassImpl()
{std::cout << "In trivially copiable constructor\n";}
};
template <class T>
using MyClass = MyClassImpl<T, std::is_trivially_copyable<T>::value>;
int main () {
MyClass<int> m1;
MyClass<std::string> m2;
}