奇技淫巧C++之返回值重载

C++当然是不能仅仅通过返回值重载函数的,但是,我们往往会想:要是支持返回值重载就好了。现在,我就从C++的某个颇受争议的角落,为您发掘一点东西。

假设有这样一个函数:

type getvalue(const DBField& fd);

可是,DBField实际的数据类型对于getvalue来说,并不了解,一个常见的解决方案是:

template<typename T>
T getvalue(const DBField& fd);


可是,这样当然是一个办法,而且是不错的办法。问题在于,有些时候我们并不方便提供这个T,比如,是一个运算符重载的时候。另外,当我们不想过早确定返回值类型的时候,我们也不愿意提供这个类型T。解决的办法很简单,提供一个间接层:

string getvalue(const DBField& fd);
int getvalue_int(const DBField& fd);
Result getvalue(const DBField& fd)
{
  return Result(fd);
}


看看如何实现Result:

struct Result{
  const DBField& fd;
  explicit Result(const DBField& f) : fd(f){}
  operator string() const { return getvalue_string(fd);}
  operator int() const { return getvalue_int(fd);}
};


现在,让我们输出数据:

void print_string(const string& str){...}
void print_int(int i){...}


如下使用:

print_string(getvalue(DBField));
print_int(getvalue(DBField));


当然,把类型写进名字可不是什么漂亮的做法,既然你喜欢重载,没问题:

template <typename T>
T getvalue(const DBField& fd);
struct Result{
  const DBField& fd;
  explicit Result(const DBField& f) : fd(f){}
  template<typename T>
  operator T() const { return getvalue<T>(fd);}
};


这个方法问题在于,必须在某个结束点提供具体的类型信息,这也是为什么我们要写两个print而不是直接用cout输出的原因。可是,话说回来,既然你打算仅仅通过返回值来重载,总要告诉代码,返回值是什么吧?

这里展示了懒惰计算的技巧,通过一个间接层,把真正的计算时刻延迟到必需的时候。也许你对返回值重载不屑一顾,但是这个技巧是非常有用的。下一次,我将用懒惰计算的方法,展示另一种技巧。

#include <iostream>
#include <string>
using namespace std;
string getvalue_slow(const int&)
{
  return "getvalue_slow";
}
string g_fast = "getvalue_fast";
const char* getvalue_fast(const int&)
{
  return g_fast.c_str();
}
struct Result
{
  const int& i;
  explicit Result(const int& r) : i(r){}
  operator string() const{ return getvalue_slow(i);}
  operator const char* () const { return getvalue_fast(i);}
};
Result getvalue(const int& i)
{
  return Result(i);
}
void print_const(const char* str)
{
  cout << str << endl;
}
void print(const string& str)
{
  cout << str << endl;
}
int main()
{
  print(getvalue(1));
  print_const(getvalue(1));
}

时间: 2024-10-29 03:14:11

奇技淫巧C++之返回值重载的相关文章

如何实现用返回值重载

今天[ IceSharK - PP.Poet ]很清纯地提出了一个问题,如何能做到函数返回值重载?简单的说,就是如何实现 string Test() {...} int Test() {...} 然后通过接受方的上下文自动选取重载: int i = Test(); string s = Test(); 当然VB或者C#都是不允许这样写的.不过IL并没有禁止这一写法,事实上在VB或C#中有一种语法结构允许按照返回值选取相应的重载,那就是隐式类型转换运算符(implicit operator或者Wi

java返回值 重载-java可否实现返回值重载

问题描述 java可否实现返回值重载 As an additional challenge, write a class with a method boolean print(int)that prints a value and returns a boolean. Now overload the method to return a long. (This is similar to some questions on the Sun Java Certification Exam.)

java返回值 重载-java当中一个匿名类或者类必须返回一个对象吗

问题描述 java当中一个匿名类或者类必须返回一个对象吗 java当中一个类必须返回一个对象吗 就象方法一样一定有个返回值,void修饰的除外 解决方案 只有方法才有返回值可言,类又不是方法,没有返回值可言.A a=new A();这叫创建一个对象并引用,而不是返回一个对象

多项式 运算符重载-利用运算符重载 定义多项式加法 返回值出错

问题描述 利用运算符重载 定义多项式加法 返回值出错 class Poly{ int n; public: int *a; Poly(){} Poly(int) { cout<<""请输入多项式的次数:""; cin>>n; a =new int [n+1]; cout<<""请依次输入各项系数 不存在该次项则输入0 最高项系数不得为0""< for(int i=0;i { cout

c++-C++里的函数重载应该只是参数不同对吧。那么不同类型的等号重载返回值不是不一样吗?

问题描述 C++里的函数重载应该只是参数不同对吧.那么不同类型的等号重载返回值不是不一样吗? C++里的函数重载应该只是参数不同对吧.那么不同类型的等号重载返回值不是不一样吗? 解决方案 参数类型不同的函数重载(C++)C++与C语言不同之四--函数重载 解决方案二: c++的函数重载要求函数名相同,形参类型不同或形参个数不同,对返回值没有要求. 虚函数重载要求函数名.形参个数.类型必须相同,这样才能通过基类指针实现多态性.

一个类如何实现两个接口中同名同参数不同返回值的函数

假设有如下两个接口: public interface IA{    string GetA(string a);}public interface IB{    int GetA(string a);} 他们都要求实现方法GetA,而且传入的参数都是一样的String类型,只是返回值一个是String一个是Int,现在我们要声明一个类X,这个类要同时实现这两个接口: public class X:IA,IB 由于接口中要求的方法的方法名和参数是一样的,所以不可能通过重载的方式来解决,那么我们该

(一二四)给类对象赋值、以及类对象的返回值

于直接给对象赋值: 之前学过,如何给对象在初始化时进行赋值. 对于C++11来说,初始化方式有三种: ① man c = man{ "cc",1 }; ② man d = { "dd",1 }; ③ man f{ "ff",1 };   假如有一类M,他有两个私有成员a和b(int类型). 于是新建一对象M q; 对象q使用默认构造函数(假如都赋值为0,这个不重要): 现在,我们想给对象q的第一个私有成员赋值,该怎么办? 这章刚学过运算符重载,难

qt4-Qt中的星期英文显示,和timerId()的返回值

问题描述 Qt中的星期英文显示,和timerId()的返回值 问题1:下面的是槽函数的定义,我想让 星期四 显示成英文应该怎么写,我Ubuntu是中文的 void MainWindow::timeUpdate() { QDateTime timeOfSystem = QDateTime::currentDateTime(); QString str = timeOfSystem.toString("yyyy-MM-dd hh:mm:ss dddd"); label->setTex

函数返回值是否使用引用类型的问题:理解引用、返回值

在<对象更有用的玻璃罩--常引用>一文中,介绍了对象作为函数的参数时,推荐使用引用的形式.并且,如果实际参数的值不允许改变时,声明为常引用更佳. 在<第8周-任务1-方案3-复数类中运算符重载(与实数运算)>中,又讨论了一个问题,结论是:在类似复数加法运算符重载这样的函数,形式参数用作为常引用最佳,如: friend Complex operator + (const Complex &c, const double &d); friend Complex oper