模板构造函数的优先级
Priority of template constructor
我有模板 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;
}
我正在尝试添加关于模板构造函数的约束,但是这段代码编译了所以我想我遗漏了一些东西,添加 enable_if 的正确方法是什么?
在您的 main()
函数中,您试图从 Foo<int>
构建 Foo<char>
。 decay-based ctor 将 not 在这里工作,因为 Foo<A>
不会衰减到 Foo<B>
即使 A
衰减到 B
.请参阅 the cppreference page on std::decay
以详细了解它的作用。
此外,我建议避免使用 pre-decay 类型的显式(模板化)构造函数。如果您的论点也是复制或移动构造函数之一(分别来自 const Foo&
和 Foo&&
)衰减为 Foo
,那么这些构造函数应该足够了。如果他们不知何故不是,那么您允许的这种隐式转换可能比它的价值更麻烦。它肯定会使您的 class 更难阅读和适应。事实上,您已经看到它导致了一个小错误 :-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;
}
我有模板 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;
}
我正在尝试添加关于模板构造函数的约束,但是这段代码编译了所以我想我遗漏了一些东西,添加 enable_if 的正确方法是什么?
在您的 main()
函数中,您试图从 Foo<int>
构建 Foo<char>
。 decay-based ctor 将 not 在这里工作,因为 Foo<A>
不会衰减到 Foo<B>
即使 A
衰减到 B
.请参阅 the cppreference page on std::decay
以详细了解它的作用。
此外,我建议避免使用 pre-decay 类型的显式(模板化)构造函数。如果您的论点也是复制或移动构造函数之一(分别来自 const Foo&
和 Foo&&
)衰减为 Foo
,那么这些构造函数应该足够了。如果他们不知何故不是,那么您允许的这种隐式转换可能比它的价值更麻烦。它肯定会使您的 class 更难阅读和适应。事实上,您已经看到它导致了一个小错误 :-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;
}