MGE
MGE

Reputation: 912

Using template in c++ - Returning values from method

I wanna a method that receives a generic type, and a generic type (that's defined in run time). In the example there's if I'm using a string type, It needs to return the first param lenght (in string); If I'm using a int type, needs to return the biggest (int integer).

Have a look:

#include "stdafx.h"
#include <sstream>
#include <iostream>
#include <conio.h>

#include <sstream>
#include <string>
#include <atldbcli.h>

#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
 no_namespace rename("EOF", "EndOfFile")

using namespace std;


class Test
{
public:
    template<class T>
    T returnVal(T valueOne, T valueTwo);
};

template<class T>
T Test::returnVal(T valueOne, T valueTwo)
{
    if(typeid(valueOne) == typeid(string))
    {
        string teste = valueOne;
        int testeInt = teste.size();
        ostringstream testeString;
        testeString << testeInt;
        teste = testeString.str();
        return teste;

    }
    else
        return valueOne > valueTwo? valueOne:valueTwo;
}


int main()
{
    string reference = "stringVal";
    Test ref;
    cout << ref.returnVal<string>(reference, "asasas") << endl;
    cout << ref.returnVal<int>(10, 485);
    getch();
    return 0;
}

However, when the main function calls ref.returnVal(10, 485); it's show a message error: 'return' : cannot convert from 'std::string' to 'int' Does anybody know what's wrong? Thanks

Upvotes: 0

Views: 108

Answers (4)

iavr
iavr

Reputation: 7637

All previous answers clearly identify the problem. As for a better way to do it:

class Test
{
public:
    string returnVal(string valueOne, string valueTwo)
    {
        string teste = valueOne;
        int testeInt = teste.size();
        ostringstream testeString;
        testeString << testeInt;
        teste = testeString.str();
        return teste;
    }

    int returnVal(int valueOne, int valueTwo)
    {
        return valueOne > valueTwo? valueOne:valueTwo;
    }
};

Upvotes: 1

TVOHM
TVOHM

Reputation: 2742

#include <string>

template <class T> 
int returnVal(T valueOne, T valueTwo);

template <>
int returnVal<std::string>(std::string valueOne, std::string valueTwo)
{
    return (int)valueOne.length();
}

template <>
int returnVal<int>(int valueOne, int valueTwo)
{
    return std::max(valueOne, valueTwo);
}

int main()
{
    int x = returnVal(std::string("Hello"), std::string("World!"));
    int y = returnVal(1,2);
    return 0;
}

Unless I'm misunderstanding you, you could achieve this with template specialization?

Upvotes: 1

sepp2k
sepp2k

Reputation: 370202

If you instantiate your template for type int, it looks like this:

int Test::returnVal(int valueOne, int valueTwo)
{
    if(typeid(valueOne) == typeid(string)) // This will be false
    {
        string teste = valueOne;
        int testeInt = teste.size();
        ostringstream testeString;
        testeString << testeInt;
        teste = testeString.str();
        return teste;

    }
    else
        return valueOne > valueTwo? valueOne:valueTwo;
}

The problem is that the then-clause of your if returns a string even though the return type of the function is int. The fact that the then-clause will never execute because typeif(valueOne) can't possible be string doesn't matter because the type checker does not care about that. All he sees is a return statement that returns a string, so that's an error.

To do what you want, you should simply overload your function for strings and remove all the string-specific code from the templated function.

Upvotes: 0

Julien Lopez
Julien Lopez

Reputation: 1021

this is not the proper way to do what you want. You can't use typeid to switch between types and do different operations, because all the different paths still have to be compiled, and inside your if you do return a string while your method returns an int.

google template specialization, that's what you need I guess...

Upvotes: 1

Related Questions