views:

1341

answers:

5

I have a simple class for which I want to overload operator as below

class MyClass
{
   public:
      int first;

      template <typename T>
      T operator () () const { return first; }  
};

And the somewhere else I have

MyClass obj;

int i = obj(); // This gives me an error saying could not deduce
               // template argument for T

Can someone help me with this error, much appreciated. Thank you.

edit:

This has something to do with the operator(), for example if i replace the function with

    template <typename T>
    T get() const { return first;}

it works. Appreciate all the responses.

A: 

Did you try int i = obj<int>();?

On Freund
Yes I did. This is explicit ? I guess I think implicit wont work.
That's because you applied the template to the operator overload and not the class.
TokenMacGuy
Do you mean this use is not allowed ? or is there a way around it ?
fadini: The compiler can only work out (implicitly deduce) template parameters (like T) by looking at the types of arguments where it is called. It never looks at the function body.
Doug
Doug: I understand. Just so I am completely clear, you are saying the explicit also shouldn't work ?i.e. int i = obj<int>(); // this did not work
This code should not compile (and does not in either gcc or comeau compilers). The correct syntax for explicitly requesting an instantiation for the operator() template would be: 'obj.operator()<int>();'. There you are calling the function 'operator()' with the specific type '<int>' with no arguments.
David Rodríguez - dribeas
fidini: explicit call should work fine
Ahmed Said
+1  A: 

If you wish the function call to be implicit then you'll have to apply the template to the class like this:

template <typename T>
class MyClass
{
  public:
  T first;

  T operator () () const { return first; }  
};

If it should be casted to another type then it should be:

template <typename T>
class MyClass
{
  public:
  T first;

  template <typename U>
  U operator () () const { return (U)first; }  
};
the_drow
I don't want it to be implicit, but I want to avoid the template use for the entire class. If I cast it using member template and the call is explicit, even then it doesn't work.
show me the current code using codepad.org
the_drow
http://codepad.org/E30yRqTU
This is the only way to do this:http://codepad.org/m6L1Ggo2Consider redesigning your program.
the_drow
wow ! Thanks a lot. Infact it worked without the cast in the return
A: 

I am not sure why this is a template in the first place, you always return an int, right? Thanks

mfawzymkh
In this class i always return an int, but where i call it I have function call obj() or obj<int>() which is a generic call, i.e. it can be to another class with first as float or something else. I want to try and keep the call interface same without referring to the data.
+1  A: 

Compiler would face a quite an ambiguity when trying to deduce template arguments from code like this

template T operator () () const { return first; }

because for

int i = obj();

T can be not only int, but any type "castable" to int.

Oleg Zhylin
+1  A: 

What you want to do is to provide a generic convector from Data to the userType. Consider something like this :

#include<iostream>
#include<string>
using namespace std;
class Data{
    public:
     std::string str;
     double var;

        template <typename UserType>
     operator UserType() const { return  UserType(var);}
};

int main()
{
Data d;
d.var = 5.5;
cout << int(d);
cout<<"\n";
return 0;
}

Is this what you needed?

siddhant3s
Thanks for the answer, but the reason I wanted to implement the operator() was that I have a templatized class which accesses a simple data structure based on a uniform interface using get and set methods. Then depending upon use one change the accessed element in the data structure without affecting the implementation.