Ivan Romanov
Ivan Romanov

Reputation: 1228

Autodetect return type of template function

I have a some classes with a function. In all classes the function has the same name and argument type but different return type. I need a some template function which can automagically detect correct template substitution without angle brackets.

Test code to illustrate question:

struct Float
{
    static Float convert(int i)
    {
        return Float{static_cast<float>(i)};
    }

    float _f;
};

struct Int
{
    static Int convert(int i)
    {
        return Int{i};
    }

    int _i;
};

template<typename T>
T convert(int i)
{
    return T::convert(i);
}


int main()
{
    Float f1 = convert<Float>(10);
    Int i1 = convert<Int>(10);

    // Float f2 = convert(10); compilation error
    // Int i2 = convert(10); compilation error

    return 0;
}

P.S. templates makes me crazy I want but can't understand them.

Upvotes: 1

Views: 108

Answers (2)

user9024799
user9024799

Reputation:

Why do you need the convert function? You can use a single argument constructor to do the same job.

struct Float
{
    Float(int i)
    {
        _f =  static_cast<float>(i);
    }

    float _f;
};

struct Int
{
    Int(int i)
    {
        _i = static_cast<int>(i);
    }

    int _i;
};

int main()
{
    Float f2 = 10;
    Int i2   = 10;

    return 0;
}

If you're worried about the implicit calls to the constructor you can make it explicit

struct Float
{
    explicit Float(int i)
    {
        _f =  static_cast<float>(i);
    }

    float _f;
};

int main()
{
    Float f2 = Float(10);
    return 0;
}

The readability of the code is affected if the function with same name and the same type of input arguments can produce different return types.

Upvotes: 0

Not sure if it's a perfect fit to your needs, but you may simulate what you want with a class and a templated conversion operator:

class convert {
    int arg;
public:
    convert(int arg) : arg(arg) {}

    template<class T>
    operator T() const {
      return T::convert(arg);
    }
};

Since template argument deduction works for templated conversion operators, you can write this:

Float f1 = convert(10);
Int i1 = convert(10);

Just like you want.

Upvotes: 7

Related Questions