我有一个模板类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;
}
我正在尝试添加关于模板构造函数的约束,但是这段代码编译了,所以我认为我缺少了一些东西,添加enable_if的正确方法是什么?
在main()
函数中,您试图从Foo<int>
构造Foo<char>
。基于衰变的ctor在这里不起作用,因为即使A
衰变为B
,Foo<A>
也不会衰变为Foo<B>
。请参阅std::decay
上的cppreference页面,以了解它的具体功能。
此外,我建议避免使用预衰减类型中的显式(模板化(构造函数。如果您的参数中的一个复制或移动构造函数(分别来自const Foo&
和Foo&&
(也衰变为Foo
,那么这些构造函数就足够了。如果它们不知何故不是,那么你所允许的这种隐含转换可能会带来更多的麻烦。这肯定会使你的课更难阅读和适应。事实上,你已经看到它导致了一个小错误:-P
除了打字错误,您还可以使用已删除的函数声明,如下所示:
#include <iostream>
#include <type_traits>
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<typename K, typename = typename std::enable_if_t<!std::is_same_v<T, K>>>
Foo (Foo<K> const&) = delete;
};
int main() {
Foo<int> ff;
Foo<int> gg(ff); //THIS WORKS
//Foo<char> dd(ff); //THIS PRODUCES ERROR
return 0;
}
演示