Deklaracja funkcji o zmiennym typie na wyjściu

1

Witam,

czy jest możliwość napisania takiej funkcji w VC++, która na wejściu przyjmuje CString (działam na MFC, stąd CString),
a na wyjściu zwróci albo int, albo CString, czy też double, w zależności od działań w jej wnętrzu?

np.

???? MyFunction (CString sText)
{
    int iWynik = 0;
    CString sWynik = L"sample text!";
    double dWynik = 13.69;

    if (sText == L"tekst 1")
       return sWynik;

    if (sText == L"tekst 2")
       return iWynik;

    if (sText == L"tekst 3")
       return dWynik;
}

main ()
{
    MyFunction(L"tekst 1");   // i zwraca mi "sample text!"
    MyFunction(L"tekst 2");   // i zwraca mi 0
    MyFunction(L"tekst 3");   // i zwraca mi 13.69
}

pozdrawiam

0

http://www.cplusplus.com/doc/tutorial/templates/
http://msdn.microsoft.com/en-us/library/ssea4yk6(v=vs.80).aspx
Btw, w C++ każda funkcja musi mieć jawnie podany swój typ (mam na myśli main).

Edit: to nie jest stricte to, co chcesz wykonać, ponieważ bez compiler-magic raczej tego nie można zrobić (a z kolei to tylko niepotrzebnie komplikowałoby sprawę, cokolwiek chcesz zrobić, można to wykonać łatwiej).
Każda funkcja musi zwracać jeden, określony typ.

1

Mozna na przyklad zwrócic unie, albo zrobic odpowiednia hierarchie klas.
Ale ogóle to jest BARDZO ZLY POMYSL i jesli chcesz cos takiego zrobic znaczy ze masz bardzo duzy blad w swoim projekcie. Napisz wiec co chcesz osiagnac a my doradzimy jak zrobic to poprawnie. Bo ten pomysl który wymysliles jest o dupe rozbic ;]

0

Zawsze możesz jeszcze zwracać to przez referencję, ale jak powiedział @Shalom - jeżeli potrzebujesz to robić, masz gdzieś błąd projektowy.

3

Wymyśliłem coś takiego:

#include <iostream>
#include <string>

using namespace std;

void* MyFunction (string sText)
{
    void* Wynik = NULL;
 
    if (sText == "tekst 1")
    {
        Wynik = static_cast<void*>(new int(32));
        return Wynik;
    }
 
    if (sText == "tekst 2")
    {
        Wynik = static_cast<void*>(new string("sample text"));
        return Wynik;
    }
 
    if (sText == "tekst 3")
    {
        Wynik = static_cast<void*>(new double(13.69));
        return Wynik;
    }
}
 
int main ()
{
    cout << *((int *)MyFunction("tekst 1")) << endl;    //zwraca mi 32
    cout << *((string *)MyFunction("tekst 2")) << endl; //zwraca mi "sample text!"
    cout << *((double *)MyFunction("tekst 3")) << endl; //zwraca mi 13.69
    return 0;
}
0

Można tak zrobić, ale to jest dość śliska sprawa - traci się kontrolę typów i trzeba wiedzieć co funkcja zwróci - czyli można napisać 3 różne funkcje i będzie to lepszym rozwiązaniem.

BTW: jak już używasz rzutowania c++ to w mainie też lepiej go użyć(reinterpret_cast). No i masz tu wyciek pamięci.

0

Skoro to MFC to możesz użyć typu VARIANT, albo nawet lepiej COleVariant.

0

C++ jest językiem mocno typowanym i taka konstrukcja nie wpasowuje się w niego. W jakimś PHPie to co innego ale w przypadku C++ takich konstrukcji się nie używa.

1
adf88 napisał(a):

C++ jest językiem mocno typowanym i taka konstrukcja nie wpasowuje się w niego. W jakimś PHPie to co innego ale w przypadku C++ takich konstrukcji się nie używa.

Używa się. W prawie każdym dużym frameworku / api istnieje odpowiednik typu variant. C++ wspiera bezpośrednio takie konstrukcje poprzez unie.

0

Chodziło mi o to, że nie używa się tego powszechnie a raczej do szczególnych zastosowań. I chodziło mi raczej o "typ dowolny" niżeli wyspecjalizowane unie czy szablony które wciąż mocno pozostają powiązane z typem danych.

0

I chodziło mi raczej o "typ dowolny" niżeli wyspecjalizowane unie czy szablony które wciąż mocno pozostają powiązane z typem danych.

Nie ma w C ani C++ czegoś takiego jak "typ dowolny". Wszystko jest jakiegoś typu.
Nawet jeśli wymyślisz taką mega-unię czy szablony, to nadal nie będzie to „dowolny typ”, tylko ten konkretny — o nazwie, powiedzmy, dowolny.

1
Patryk27 napisał(a):

http://www.cplusplus.com/doc/tutorial/templates/
http://msdn.microsoft.com/en-us/library/ssea4yk6(v=vs.80).aspx
Btw, w C++ każda funkcja musi mieć jawnie podany swój typ (mam na myśli main).

Edit: to nie jest stricte to, co chcesz wykonać, ponieważ bez compiler-magic raczej tego nie można zrobić (a z kolei to tylko niepotrzebnie komplikowałoby sprawę, cokolwiek chcesz zrobić, można to wykonać łatwiej).
Każda funkcja musi zwracać jeden, określony typ.

Dziękuję wszystkim za informację, odpowiedzi i polemikę :)
Problem jest dla mnie dość nietypowy (a nie ukrywam, że daleko mi do profesjonalnego programisty C++), a mianowicie całość jest powiązana z bibliotekami firmy Autodesk (Autocad, ObjectARX) i przy szukaniu podpowiedzi z tamtej strony, odsyłano mnie do C++ (bo tutaj rozwiązanie ponoć się znajduje)..
Program pobiera na wejściu CString, a następnie polecenie systemowe AutoCADa "getvar", odwołujące się do przechowywanych przez niego wartości, zwraca nam te wartości.

Dla przykładu:
nazwa na wejściu, odwołująca się do wartości trybu lokalizacji (getvar "OSMODE"), zwraca na wyjściu wartość **Integer **np. 1 lub 0.
a następna może być (getvar "CLAYER") zwróci nam **CString **"0" lub "MyLayer".

Problemem jest właśnie to, że w chciałem funkcję, która sama dostosuje swój typ, do tego co uzyskam w odpowiedzi z funkcji "getvar".
Niemniej, po Waszej dyskusji, zrozumiałem dlaczego jest to trudne, a zarazem nieprawidłowe z punktu programowania w C++.
Zgodnie z sugestiami, stworzę kilka metod, gdzie każda będzie obsługiwała dany typ zmiennych (CString, integer, double itd.) i postaram się jakoś zabezpieczyć całość ErrHandle. Po prostu zanim wywołam "getvar", muszę wiedzieć jakiego typu odpowiedzi oczekiwać...

pozdrawiam

0

Ewentualnie zwracaj strukturę zawierającą pola typu string, int, itd. oraz dodatkowe pole typu int (lub enum) określające typ wyniku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1