返回类型的C++11 方法模板专用化
C++11 method template specialization for return type
>我有以下类:
class Foo {
public:
template <typename T>
T bar() {
cout << "Called with return type: " << typeid(T).name() << endl;
T t = //... (some implementation here)
return t;
}
}
它按以下方式调用:
Foo foo;
int i = foo.bar<int>();
long l = foo.bar<long>();
现在,我想对使用shared_ptr<T>
调用函数的情况有不同的专业化
Foo foo;
foo.bar<shared_ptr<int>>();
foo.bar<shared_ptr<long>>();
但是,当然,我不想为每种类型创建完全专业化。是否有可能实现这种行为(如果需要,可以基于特征)?
您不能部分专用化功能。有关原因的故事,请查看此GOTW。
不过,您可以部分专业化课程,因此您可以做的是:
template <typename T>
T bar() {
return bar_impl<T>::apply(this);
}
哪里:
template <typename T>
struct bar_impl {
static T apply(Foo* ) {
// whatever
}
}
template <typename T>
struct bar_impl<std::shared_ptr<T>> {
static std::shared_ptr<T> apply(Foo* ) {
// whatever else
}
}
当然有很多方法可以做到这一点。 我想到的第一种方法就是函数重载。 由于您没有要重载的参数,因此您必须创建一个。 我喜欢指针,它有效地充当将类型传递给函数的一种方式。
class Foo {
//regular overload
template<typename T>
T bar(T*) { //takes a pointer with an NULL value
cout << "Called with return type: " << typeid(T).name() << endl;
T t = //... (some implementation here)
return t;
}
//shared_ptr overload - NOTE THAT T IS THE POINTEE, NOT THE SHARED_PTR
template<typename T>
std::shared_ptr<T> bar(std::shared_ptr<T>*) { //takes a pointer with an null value
cout << "Called with return type: " << typeid(T).name() << endl;
std::shared_ptr<T> t = //... (some implementation here)
return t;
}
public:
template <typename T>
T bar() {
T* overloadable_pointer = 0;
return bar(overloadable_pointer);
}
};
我从未听说过其他人使用指针来传递类型,所以如果您选择这样做,请彻底评论,只是为了安全起见。 这是奇怪的代码。
简单地使用帮助程序结构进行模板专用化可能更直观,这是大多数人会做的。 遗憾的是,如果您需要访问 Foo
的成员(您可能这样做),使用模板专用化将需要您将所有这些成员传递给函数,或者与模板帮助程序交朋友。 或者,您可以将type_traits专用化的东西传递给另一个成员,但这最终只是上面指针技巧的复杂版本。 许多人发现它更正常,不那么令人困惑,所以这里是:
template<typename T>
struct Foo_tag {};
class Foo {
//regular overload
template<typename T>
T bar(Foo_tag<T>) {
}
//shared_ptr overload - NOTE THAT T IS THE POINTEE, NOT THE SHARED_PTR
template<typename T>
std::shared_ptr<T> bar(Foo_tag<std::shared_ptr<T>>) {
}
public:
template <typename T>
T bar() {
return bar(Foo_tag<T>{});
}
}
由于还没有人提出,可以使用SFINAE来区分T
和std::shared_ptr<U>
:
template <typename T>
struct is_shared_ptr_impl : std::false_type {};
template <typename T>
struct is_shared_ptr_impl<std::shared_ptr<T>> : std::true_type {};
template <typename T>
using is_shared_ptr = typename is_shared_ptr_impl<typename std::decay<T>::type>::type;
class Foo
{
public:
template <typename T>
auto bar()
-> typename std::enable_if<!is_shared_ptr<T>{}, T>::type
{
std::cout << "T is " << typeid(T).name() << std::endl;
return {};
}
template <typename T>
auto bar()
-> typename std::enable_if<is_shared_ptr<T>{}, T>::type
{
using U = typename std::decay<T>::type::element_type;
std::cout << "T is shared_ptr of " << typeid(U).name() << std::endl;
return {};
}
};
演示
相关文章:
- 检查子类型时的专用方法模板
- 部分方法专用化
- 基于枚举参数调用专用模板方法
- 类中一种方法的部分专用化
- 从非模板类调用专用模板方法
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- 没有针对完全专用模板类的外联虚拟方法定义
- 从部分专用模板方法调用模板非静态方法
- 添加具有模板专用化的方法
- 常量字符*的模板方法专用化
- 两种专用方法中的相同代码
- C++隐式/显式模板方法专用化问题
- C++复杂类型的单一方法的模板专用化
- enable_if在类声明之外实现的方法专用化
- 模板化类和模板化方法的模板专用化语法
- 获取非专用标准::矢量容器的标准方法<bool>
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- boost:enable_if 在模板化类中定义专用方法
- 模板类的专用方法
- 从专用方法捕获异常