根据返回值类型重载函数

  
根据返回值类型重载函数
 Wanderley Caloni
介 绍
这份代码展示了一种用函数返回值代替函数参量标来使用C++重载函数规则的方法。当然,不更改语言本身,返回值看起来就像以返回类型的重载。

背 景
函数重载,换句话说,重用一个已存在的函数名但用不同的参量标,这在C++、Java和.NET社区或多或少都知道一些。作为必要条件,我们都知道,一个重载函数的特征标必须不同于它的同型函数。说明代码如下:
GUID guid;
wstring guidS;
CreateNewGUID(guidS); // calls void CreateNewGUID(wstring&)
CreateNewGUID(guid); // calls void CreateNewGUID(GUID&) (the compiler knows that)
 
接受不同的输入形式是很一般的方式。但是如果是输出形式不同又会怎么样呢?如果不传递结果变量作为输出参数,那么怎样以一种不同的形式使用重载特性来提取不同或相同的信息呢?让我们来想像一下一种合理的构造可能是怎样的呢,我们可能想到像这样的一些结果:
GUID guid;
wstring guidS;
guidS = CreateNewGUID(); // calls wstring CreateNewGUID()
guid = CreateNewGUID(); // calls GUID CreateNewGUID() (the compiler knows that?)
 
再一次打开我们那翻烂了的旧 C++ 理论课本,我们看到上面的代码是不能工作的。或者至少,不应该会,像这样定义的两个函数会导致如下的错误:
      error C2556: 'GUID CreateNewGUID(void)' : overloaded function differs only by return type from 'std::wstring CreateNewGUID(void)'
 
这是正确的,哦,错误是正确。返回类型不是能标识函数唯一性的属性。只有特征标才能表示(函数收到的参量)。 AFAIK ,这个限制是防黑客的。不管怎么样,除了一般函数之外,没什么允许我们使用另一个特征。:

struct CreateNewGUID
{
   // what is supposed to be here?
};


我们找到了!现在我们能够“调用”我们的“函数”了。这个“函数”创造一个新的结构体实例并且将“返回值”赋给一个wstring或这我们的GUID结构体:
guidS = CreateNewGUID(); // instanciates a CreateNewGUID
guid = CreateNewGUID(); // instanciates a CreateNewGUID. The difference is in the "return"

使用代码
既然我们创造了一个新的类型,并且知道这个新的类型是不同于已知的wstring和GUID,我们应该将新的类型转换成需要的类型:
struct CreateNewGUID
{
   operator wstring () { ... } // the conversion is the "function call"

   operator GUID () { ... } // as there's a couple of conversions... over... underload!
};
这最后得到了我们要通过返回值重载“函数”的方法:
// instanciates a CreateNewGUID e calls CreateNewGUID::operator wstring()
guidS = CreateNewGUID();

// instanciates a CreateNewGUID e calls CreateNewGUID::operator GUID()
guid = CreateNewGUID();

下面是完整的代码:
/* @file underload.cpp
  @brief A way to make overload using just the return type.
@author Wanderley Caloni
*/
#include <windows.h>
#include <objbase.h>

#include <IOSTREAM>
#include <string>

using namespace std;

struct CreateNewGUID
{
   operator wstring () // the first function...
   {
      GUID guid = operator GUID();
      OLECHAR buf[40] = { };
      ::StringFromGUID2(guid, buf, sizeof(buf));
      return wstring(buf);
   }

   operator GUID () // ... and its "underload"
   {
      GUID guid = { };
      ::CoCreateGuid(&guid);
      return guid;
   }
};
</string> </IOSTREAM></objbase.h></windows.h>

目的(POI)
这段代码很长一段时间就写出来了,作为回答我一个朋友的疑问。学会了它,C++比我们想像的更有威力。我们总能以这样或那样的形式得到我们想要的。



原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值