Intent

To increase the flexibility of a class template's interface by allowing the class template to participate in the same implicit type conversions (coercion) as its parameterizing types enjoy.

Also Known As[edit]

Motivation[edit]

It is often useful to extend a relationship between two types to class templates specialized with those types. For example, suppose that class D derives from class B. A pointer to an object of type D can be assigned to a pointer to B; C++ supports that implicitly. However, types composed of these types do not share the relationship of the composed types. That applies to class templates as well, so a Helper<D> object normally cannot be assigned to a Helper<B> object.

class B {};
class D : public B {};
template <class T>
class Helper {}; B *bptr;
D *dptr;
bptr = dptr; // OK; permitted by C++ Helper<B> hb;
Helper<D> hd;
hb = hd; // Not allowed but could be very useful

There are cases where such conversions are useful, such as allowing conversion from std::auto_ptr<D> to std::auto_ptr<B>. That is quite intuitive, but isn't supported without using the Coercion by Member Template Idiom.

Solution and Sample Code[edit]

Define member template functions, in a class template, which rely on the implicit type conversions supported by the parameter types. In the following example, the templated constructor and assignment operator work for any type U, for which initialization or assignment of a T * from a U * is allowed.

通过在一个类中定义成员模板函数,可以使不同类型的参数得到隐士转换。

template <class T>
class Ptr
{
public:
Ptr () {} Ptr (Ptr const & p)
: ptr (p.ptr)
{
std::cout << "Copy constructor\n";
} // Supporting coercion using member template constructor.
// This is not a copy constructor, but behaves similarly.
template <class U>
Ptr (Ptr <U> const & p)
: ptr (p.ptr) // Implicit conversion from U to T required
{
std::cout << "Coercing member template constructor\n";
} // Copy assignment operator.
Ptr & operator = (Ptr const & p)
{
ptr = p.ptr;
std::cout << "Copy assignment operator\n";
return *this;
} // Supporting coercion using member template assignment operator.
// This is not the copy assignment operator, but works similarly.
template <class U>
Ptr & operator = (Ptr <U> const & p)
{
ptr = p.ptr; // Implicit conversion from U to T required
std::cout << "Coercing member template assignment operator\n";
return *this;
} T *ptr;
}; int main (void)
{
Ptr <D> d_ptr;
Ptr <B> b_ptr (d_ptr); // Now supported
b_ptr = d_ptr; // Now supported
}

http://en.wikibooks.org/wiki/More_C++_Idioms/Coercion_by_Member_Template

C++惯用法:通过成员模板实现隐式转换(Coercion 强迫 by Member Template)的更多相关文章

  1. C++模板之隐式实例化、显示实例化、隐式调用、显示调用和模板特化详解

    模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程.对于函数模板而言,模板实例化之后,会生成一个真正的函数.而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始 ...

  2. Scala 隐式转换及应用

    什么是隐式转换 我们经常引入第三方库,但当我们想要扩展新功能的时候通常是很不方便的,因为我们不能直接修改其代码.scala提供了隐式转换机制和隐式参数帮我们解决诸如这样的问题. Scala中的隐式转换 ...

  3. scala成长之路(3)隐式转换

    不废话,先上例子:定义一个参数类型为String的函数: scala> def sayHello(name:String) = println("hello " + name ...

  4. C++ 不具有继承关系的类之间的显式,隐式转换 2013-07-11 15:41

    好久没有写blog了,今天在学习c#的时候看到某一章节 讲类的隐式与显式转换.特此留笔,以供后续参考之用. 关于显式,隐式转换有些争论,说什么不建议隐式转换.但是个人认为非必要,如果有良好的基础书写基 ...

  5. 显示转换explicit和隐式转换implicit

    用户自定义的显示转换和隐式转换 显式转换implicit关键字告诉编译器,在源代码中不必做显示的转型就可以产生调用转换操作符方法的代码. 隐式转换implicit关键字告诉编译器只有当源代码中指定了显 ...

  6. Scala特性: 隐式转换

    1.隐式转换特征: 1)隐式参数的用法 · 获取可能的预期类型 · 获取预期类型,并且拥有预期类型的行为 · 对信息进行补充说明(一般用函数做隐式参数的比较多) 2)隐式类: 3)隐式method:

  7. 深入理解Scala的隐式转换系统

    摘要: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码.   使用方式: 1. ...

  8. QStringLiteral(源代码里有一个通过构造函数产生的从const char*到QString的隐式转换,QStringLiteral字符串可以放在代码的任何地方,编译期直接生成utf16字符串,速度很快,体积变大)

    原作者: Olivier Goffart 点击打开链接http://woboq.com/blog/qstringliteral.html 译者: zzjin 点击打开链接http://www.tuic ...

  9. F#中的自定义隐式转换

    我们知道隐式变换在可控情况下会使代码变得简洁.熟悉C#的都知道C#中可以自定义隐式变换,例如 public class A { private int data; public static impl ...

随机推荐

  1. 2013杭州网络赛D题HDU 4741(计算几何 解三元一次方程组)

    Save Labman No.004 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  2. centos6.5设备mysql5.6

    1. 首先检查版本号number # uname -a 要么 # cat /etc/redhat-release CentOS release 6.6 (Final) 2. 下载并安装Mysql的yu ...

  3. c++栈管理库TCMalloc、jeMalloc

    示例:http://blog.csdn.net/chosen0ne/article/details/9338591

  4. C++之static_cast, dynamic_cast, const_cast

    转自:http://www.cnblogs.com/chio/archive/2007/07/18/822389.html 首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 ...

  5. 记录一次webbrowser无法加载 activex 遇到的问题

    关联配置: win7 x64 Adobe Reader XI activex 安装目录X84 笔者项目运行Any CPU 无论如何也加载不出PDF 刚开始还以为自己封装的控件XWebBrowser的问 ...

  6. java线程的使用(Runnable)

    在实际项目开发过程中,线程是经常要用到的,特别是为了不影响项目的运行效果. 以下就以实际项目中的简单例子来介绍: public class SystemRedisInfoController exte ...

  7. [Jobdu] 题目1361:翻转单词顺序

    题目描述: JOBDU最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,“stu ...

  8. JBoss 系列六十九:CDI 基本概念

    概述 如果说EJB,JPA是之前JEE(JEE5及JEE5之前)中里程碑式的规范,那么在JEE6,JEE7中CDI可以与之媲美,CDI(Contexts and Dependency Injectio ...

  9. (Problem 41)Pandigital prime

    We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly o ...

  10. C# 读书笔记之访问关键字this和base

    this 关键字引用类的当前实例.静态成员方法中不能使用this关键字,this关键字只能在实例构造函数.实例方法或实例访问器中使用. base 关键字用于从派生类中访问基类的成员. 指定创建派生类实 ...