1

I use templates, and I am annoyed with calling the functions with the template parameters. Example:

I have a templated structure

template<typename T>
struct telement {
    typedef {
        T element;
        float some_value;
    } type;
};

telement<float>::type theElement;

and I have a function:

template<typename T>
float do_some_stuff( const typename telement<T>::type& x) {
    // ...
}

Unfortulately, g++ complains when I call

do_some_stuff( theElement );

and I must call:

do_some_stuff<float>( theElement );

Can I avoid template specification each time I call the function? I thought that compiler should figure out the type automagically...

Jakub M.
  • 32,471
  • 48
  • 110
  • 179

2 Answers2

4

This is one of the non-deducible contexts. The template argument T cannot be deduced by the compiler.

Ask this question yourself : when you write this,

do_some_stuff( theElement );

what type argument do you think should be decuded for T?

You probably think T=float? Well, that is just one possibility. There could exist a specialization for the class template as:

//the compiler cannot assume that such specialization doesn't exist!
template<>
struct telement<someType>
{
    typedef {
        float element;
        float some_value;
    } type;
};

Then even in this case, the nested type telement<someType>::type is same as telement<float>::type. You see the ambiguity? There is no one-one relationship between T and nested type. There could be in fact many-one relationship. There could be many T for which the nested type would be same, identical.

So given the nested type, how can the compiler decide template argument? It cannot

There are already several topics on SO which explains similar situations, see these:


The solution is, just write the function template as:

template<typename T>
float do_some_stuff( const T& x) {
    // ...
}

After all, what is the point of writing telement<T>::type in the parameter?

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

Here's a way to work with it:

#include <iostream>


template<typename T>
struct telement {
    typedef struct {
        typedef T t_element_type;
        typedef float t_value_type;

        t_element_type element;
        t_value_type some_value;
    } type;
};


template<typename T>
float imp_do_some_stuff(const typename telement<T>::type& x) {
    return x.some_value;
}

template<typename T>
float do_some_stuff(const T& x) {
    return imp_do_some_stuff<typename T::t_element_type>(x);
}

int main() {
    telement<float>::type theElement;

    do_some_stuff(theElement);
    return 0;
}
justin
  • 104,054
  • 14
  • 179
  • 226