1つだけ過去を変えられるとしたら?

戻り値というより、受け側によって関数の振る舞いを変えたいのですが、
C++では、同名、同パラメータはC2556のコンパイルエラーになります。

Perlでいうリスト値を返すかスカラー値を返すかは呼び出し側によるようなことをしたいのですが、C++では無理でしょうか?

下の例では、//...部分は戻り値によって異なるのでC++のテンプレート?では無理そうですが、そんなことはC++でできるのでしょうか?
似たようなテクニックでも構いませんので、知識の豊富な方、教えてください。

#include <iostream>
#include <string>

using namespace std;

class A {
public:
A(){}
~A(){}
int test(int x, int y){
          //...
return 0;
}
string test(int x, int y){
// ...
return "";
}
};


void main(void){
A a;
int ret1 = a.test(1,2);
string ret2 = a.test(1,2);

cout << endl << "End..." << endl;

}

A 回答 (4件)

決してお勧めはしませんが...



class A
{
public:
 class B
 {
  A* a_;
  int x_, y_;
 public:
  explicit B(A* a, int x, int y) : a_(a), x_(x), y_(y) {}
  template <class T>
   operator T() const;
 };
 B test(int x, int y)
 {
  return B(this, x, y);
 }
};

template<> A::B::operator int() const { return 0; }
template<> A::B::operator std::string() const { return ""; }

int main()
{
 A a;
 int i = a.test(1, 2);
 std::string s = a.test(1, 2);
}

とすれば解決できそうです。GCCではコンパイルできました。
(移植性があるかどうかは未確認)
    • good
    • 0

お勧めできるかどうかは別として、見かけが、普通の関数に見える方法としては、zwi さんのお書きになっている2)を準用すると。



class func()
{
public:
func(int a, int b)
{ // コンストラクタ
// ここで初期的に必要な処理
}

operator int()
{
// 返値が int の場合(実際には、int への型変換関数)
return 0;
}

operator string()
{
// 同じく string 用
return "";
}
};

等とできます。
これで、

int ret1 = func(1,2);
string ret2 = func(1,2);

は、ちゃんと、それなりの動きをします。
動作としては、返値の型を変えているのではなくて、func というクラスのインスタンスを生成して、それを、int なり string に型変換したというものです。
    • good
    • 0

普通に考えて



int test(int, int)
std::string test(int, int)

の両方が定義できてしまうと、

ret1 = a.test(1, 2);

が「正当な」代入であるか判断できませんよね。

ret1 = a.test<std::string>(1, 2);

とできるように

template<typename T>
T test(int, int) {
...
}

とするとか?
    • good
    • 0

方法は3つですかね。



(1)戻り値は諦めて、パラメータ参照渡しにして関数自身をオーバーロードする。
(2)関数の結果を直接返さずに、クラス内に保持させて別関数で返すか、型変換のオーバーロードを使用する。
(3)完全にコンパイラをだます方法としては、パラメータが違えばオーバーロードできるので、ダミーのパラメータを片方につける。

って(3)は、だまし討ちなのでお勧めしませんが。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!