Home Using a template function with different returns for different types doesn't work
Reply: 2

Using a template function with different returns for different types doesn't work

Niteraleph
1#
Niteraleph Published in 2018-01-12 01:56:17Z

so I wrote something like that:

class MyClass
{
    enum varType {INTEGER, DOUBLE, VECTOR};

    int beautiful_integer;
    double awesome_double;
    std::vector<float> many_floats;

    template <class T>
      T getVariable(varType type)
      {
          if(type == INTEGER)
          {
             return beatiful_integer;
          }
          if(type == DOUBLE)
          {
             return awesome_double;
          }
          if(type == VECTOR)
          {
             return many_floats;
          }
      }

...

};

But my compiler throws error "In instantiation of ..." and basically tells me that the return types don't match (and lists all of the unmatched ones, except the right one) and then tries to instantiate it with another type (for example double) and tells me that the return type doesn't match with int and vector of floats.

What am I doing wrong and how to properly write a template function in order to return different types depeneding on the parameter it was called with. For example when I call:

MyClass some_class(); //EDIT: this should be MyClass some_class; 
                      //thanks for pointing it out
int some_number = some_class.getVariable(INTEGER);

I want to assign the value of beautiful_integer to some_number

songyuanyao
2#
songyuanyao Reply to 2018-01-12 02:54:53Z

Template parameters are determined at compile time. You can accomplish it by template specializations. Don't use enum. e.g.

class MyClass
{
    int beautiful_integer;
    double awesome_double;
    std::vector<float> many_floats;

    template <class T>
    T getVariable();

    template<>
    int getVariable<int>
    {
        return beatiful_integer;
    }

    template<>
    double getVariable<double>
    {
        return awesome_double;
    }

    template<>
    std::vector<float> getVariable<std::vector<float>>
    {
        return many_floats;
    }

};

From C++17 you can also use Constexpr If, e.g.

template <class T>
T getVariable()
{
    if constexpr (std::is_same_v<T, int>)
    {
        return beatiful_integer;
    } 
    else if constexpr (std::is_same_v<T, double>)
    {
        return awesome_double;
    } 
    else if constexpr (std::is_same_v<T, std::vector<float>>)
    {
        return many_floats;
    } 
    else
    {
        ...
    }
}

then

MyClass some_class;
int some_number = some_class.getVariable<int>();

BTW: MyClass some_class(); doesn't do what you expect. See most vexing parse.

Jarod42
3#
Jarod42 Reply to 2018-01-12 11:08:35Z

As alternative, with std:

template <class T>
const T& getVariable() const
{
    return std::get<const T&>(std::tie(beautiful_integer, awesome_double, many_floats));
}

template <class T>
T& getVariable()
{
    return std::get<T&>(std::tie(beautiful_integer, awesome_double, many_floats));
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.345721 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO