I have the template class Foo:
template<class T>
class Foo {
public:
Foo() = default;
Foo(const Foo&) = default;
Foo(Foo&&) = default;
Foo& operator=(Foo&&) = default;
Foo& operator=(const Foo&) = default;
template<class U, typename = typename std::enable_if<
!std::is_same<typename std::decay<U>::type, Foo>::value>::type>
Foo(U&&) {
}
};
int main() {
Foo<int> ff;
Foo<char> dd(ff); //here I want a compiler error
Foo<int> e(15); //it should work
return 0;
}
I’m trying to add constraints about template constructor, however this code compiles so I think I’m missing something, what’s the proper way to add the enable_if?
>Solution :
In your main() function, you’re trying to construct a Foo<char> from a Foo<int>. A decay-based ctor will not work here, as Foo<A> does not decay into Fooeven ifAdecays intoB. See [the cppreference page on std::decay`]1 for a detailed explanation of what it does, exactly.
Also, I would suggest avoiding explicit (templated) constructors from pre-decay types. If your argument too one of the copy or move constructors (from const Foo& and Foo&& respectively) decays into a Foo, then those ctors should be enough. And if they somehow aren’t, this implicit conversion that you’re allowing for is probably more trouble than it’s worth. It will certainly make your class more difficult to read and to adapt. You have, in fact, already seen it has led you to a minor bug 😛