views:

110

answers:

3

After some trial and a lot of error, I have come to find out that it is not very useful to template operators. As an Example:

class TemplateClass
{
  //Generalized template
  template<TType>
  TType& operator[](const std::string& key)
  {
    return TType;
  }
  //Specialized template for int
  template<>
  int& operator[]<int>(const std::string& key)
  {
    return 5;
  }
  //Specialized template for char
  template<>
  char& operator[]<char>(const std::string& key)
  {
    return 'a';
  }
}
int main()
{
  TemplateClass test;
  //this will not match the generalized template.
  test["test without template will fail"]; 
  //this is not how you call an operator with template.
  test<char>["test with template will fail"];
  //this works!
  test.operator[]<int>["test will work like this"];
  return 0;
}

So to make an operator with a template is pretty ugly (unless you are into verbose, and really who is?) This is why I have been using a function "get" in lieu of operators. My question is why the ugliness? Why is it required to include the operator key word. My guess is that it has to do with some back end magic of transforming operators to not use parentheses to take arguments, and is there any way around this? Thanks in Advance.

+2  A: 

This isn't specifically an issue of templates. It's a grammar issue. What you're doing is odd in that you're only changing the return type. Had you changed the operator parameters, you wouldn't have to explicitly provide the type for the template. Since you do need to provide type, you need to explicitly call the operator to apply the parameter because it's the only way.

Check out the grammar for complete details.

JoshD
This. The grammar to differentiate `<>` template parameters from the comparison operators is gnarly.
Steve Jessop
I can only imagine it's an exercise in sadism.
JoshD
Jericho Kain
@Jericho Kain: Doing things in a 'clever' way like this lead to awful awful code. Never do this in practice. Make things simple and clear. It's better for everyone.
JoshD
+1  A: 

Return types cannot be used for overloading resolution. The only difference in the signatures of your operator[] declarations is in their return types, so as soon as you had two of them, the compiler had no hope of disambiguating your call test["test without template will fail"];

Eric Towers
A: 

Yes, template argument deduction is not working with function return types to be simple. However template operator overloading is really useful and can be applied in some completely tremendous ways.

Below there is a code sample from boost::phoenix.

for_each(c.begin(), c.end(),
    if_(arg1 % 2 == 1)
    [
        cout << arg1 << ' '
    ]
);

As you might understand it is an easy way to print out all the odd elements in a container. Kinda magic.

Keynslug