4

I'd like to have different variable value depending on type of input variable. Code:

template <typename T>
int getValue(vector<T> & data)
{
    return something; // There should be 0 for int and 1 for double
}

Do anyone know how to achieve such a functionality?

miqelm
  • 354
  • 4
  • 13
  • 1
    Looks like you are trying to switch on types. You probably have a design flaw. – Baum mit Augen Oct 12 '15 at 12:49
  • 2
    @BaummitAugen So template specialization and function overloading is flawed by design? There are perfectly valid reasons to switch on types, especially as long as you use dispatching mechanisms the language provides, and not if-else. – TheOperator Oct 12 '15 at 12:55
  • 2
    @TheOperator *"So template specialization and function overloading is flawed by design?"* No, of course not. But something that returns different integer values for different types certainly looks fishy. – Baum mit Augen Oct 12 '15 at 13:05

3 Answers3

6

If you are just dealing with an int and double then you could just overload the function for the differnt types of vectors.

int getValue(vector<int> & data)
{
    return 0;
}

int getValue(vector<double> & data)
{
    return 1;
}

If you want to keep getValue as a template function and specialize for int and double then you could use

template<typename T>
int getValue(std::vector<T> & data)
{
    return -1;
}

template <>
int getValue(std::vector<int> & data)
{
    return 0;
}

template <>
int getValue(std::vector<double> & data)
{
    return 1;
}

Live Example

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
2

You can provide non-template overloads while keeping the template. Since function resolution prefers non-template matches over templates. Example:

template <typename T>
int getValue( std::vector<T> & data )
{
    return -1; // default template
}

int getValue( std::vector<int> & data )
{
    return 0; // int overload
}

int getValue( std::vector<double> & data )
{
    return 1; // double overload
}

Here's an example using specialization:

template <typename T>
int getValue( std::vector<T> & data )
{
    return -1; // default template
}

template <>
int getValue<int>( std::vector<int> & data )
{
    return 0; // int specialization
}

template <>
int getValue<double>( std::vector<double> & data )
{
    return 1; // double specialization
}
bku_drytt
  • 3,169
  • 17
  • 19
0

Two important operators to type manipulation is typeid and decltype.

typeid return a object type_info with type information.

Some ways of verify types is:

  • std::is_same
  • typeid
  • function overload

If you are using c++11 the better option should be std::is_same with a delctype (detects the type of variable), because it's compile time resolution.

    vector<int> integers;
    vector<double> doubles;

    cout << is_same<vector<int>, decltype(integers)>::value << endl;
    cout << is_same<vector<int>, decltype(doubles)>::value << endl;
    cout << is_same<vector<double>, decltype(integers)>::value << endl;
    cout << is_same<vector<double>, decltype(doubles)>::value << endl;

If you are using standard C++ (c++98), you can use typeid operator

    vector<int> vectorInt;

    vector<int> integers; 
    vector<double> doubles;

    cout << ( typeid(integers) == typeid(vectorInt) ) << endl;
    cout << ( typeid(doubles) == typeid(vectorInt) ) << endl;

You can use function overload and templates to resolve this types without unexpected broke.

At this way do you need write a function to each type to identify or the template function will return -1 (unknow) like identification.

template<typename T> 
int getTypeId(T) {
        return -1;
}       

int getTypeId(vector<int>) {
        return 1;
}       

main() {
        vector<int> integers;
        vector<double> doubles;
        vector<char> chars;

        cout << getTypeId(integers) << endl; 
        cout << getTypeId(doubles) << endl;
        cout << getTypeId(chars) << endl;
}
David Kennedy
  • 370
  • 2
  • 12