C++单个构造函数模板专用化
C++ single constructor template specialization
对不起,如果这是一个骗局。有许多类似的问题,但似乎没有一个真正解决这个问题。它们都有点不同。
所以我想要实现的是:考虑一个模板类X<T>
。现在,我想要一个额外的构造函数extists用于该模板的特定实例化,让我们说指针X<T*>
.我不想为 X<T*>
创建一个完整的模板规范,因为X<T*>
应该与通常的模板完全相同(而且该模板是巨大的,因此复制粘贴将是一种代码重复的味道),只是它有一个额外的构造函数。我也不想从X<T>
继承X<T*>
因为我不想在这两者之间建立子类型关系。这可能吗?我是这样试过的:
template<T> class X{};
template<T> X<T*>::X(int i){...}
但它不编译。这在某种程度上可能吗?
你可以做这样的事情,使用 SFINAE:
#include <iostream>
#include <type_traits>
template<class T> class X{
public:
X(int i) {
init();
}
private:
template<class U = T>
typename std::enable_if<std::is_pointer<U>::value>::type init() {
std::cout << "It's a pointer!n";
}
template<class U = T>
typename std::enable_if<!std::is_pointer<U>::value>::type init() {
std::cout << "It's not a pointer!n";
}
};
int main() {
X<int> a(1);
X<int*> b(2);
}
哪些输出:
It's not a pointer!
It's a pointer!
你没有重载构造函数,但你正在实现你想要的。
请注意,您需要 C++11 才能使用此代码。
编辑:好的,这段代码完全符合您的要求:
#include <iostream>
#include <type_traits>
template<class T> class X{
public:
template<class U = T, class enabler = typename std::enable_if<std::is_pointer<U>::value, T>::type>
X(int i) {
std::cout << "It's a pointer!n";
}
template<class U = T, class enabler = typename std::enable_if<!std::is_pointer<U>::value, T*>::type>
X() {
std::cout << "It's not a pointer!n";
}
};
int main() {
X<int> a;
X<int*> b(2);
}
它仍然输出与以前相同。请注意,这不是一个好的设计。根据您的模板参数使用一些构造函数是很奇怪的。不过,此代码解决了您的问题。
这是一个使用 boost 但不需要 C++11 的解决方案。 在任何一种情况下,X
都有一个接受单个参数的构造函数。 当T
是一个指针时,它期望的参数是一个int
。 当T
不是指针时,参数是调用方无法访问的类型。
#include <boost/type_traits.hpp>
template < typename T >
class X
{
private:
// Declare a private type that will be used to prevent a single-argument
// constructor from being callable when T is not a pointer.
struct T_must_be_a_pointer;
public:
// Branch at compile-time based on T:
// - If T is a pointer, then declare the X( int ) constructor.
// - If T is not a pointer, then declare X( T_must_be_a_pointer ) constructor.
explicit X( typename boost::mpl::if_< boost::is_pointer< T >,
int,
T_must_be_a_pointer >::type i )
{}
};
int main() {
X<int> a();
// Next line will fail to compile:
// X<int> b(1);
X<int*> c(2);
return 0;
}
相关文章:
- 具有常量引用参数的函数模板专用化
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 如何减少函数模板专用化?
- 专用于类型集的函数模板
- 类成员函数的函数模板专用化
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- 将 c++ 类成员函数专用于模板类
- 类和成员函数模板专用化出错
- C++ 模板化基类的函数模板专用化
- 如何使专用函数模板成为某个类的朋友?
- 函数模板(它是类模板的成员)的显式专用化会产生"partial specialization is not allowed"错误,为什么?
- 函数模板中的显式模板专用化不起作用
- C++函数模板专用化和重载
- 无法专用化函数模板'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
- 函数模板专用化生成链接错误
- 视图和跨步视图以及常量噩梦的函数模板专用化
- 函数模板重载 - 部分专用化
- 64 位 G++ 4.6.3 不会在专用函数模板中将长整型视为长整型,即使它们的大小相同。这是一个错误吗?
- 为什么我不能专用函数模板?
- 专用函数模板