1

I have some code.

#include <iostream>

template<typename T>
struct Test
{
   Test(bool v):flg(v) { }
   void func() { }
   typedef void (Test::*unspecified)();
   operator unspecified() const
   {
      return flg ? &Test::func : 0;
   }
   bool flg;
};

template<typename T>
std::ostream& operator << (std::ostream&, typename Test<T>::unspecified);

int main()
{
   Test<int> t(true);
   std::cout << t << std::endl;
}

Output is

1

It works fine, but i want to get undefined reference. If Test is not template class i get undefined reference. So, why compiler not use operator << for function type and do standart conversion from pointer to class-member to bool?

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • See [Why is the template argument deduction not working here?](http://stackoverflow.com/questions/1268504/why-is-the-template-argument-deduction-not-working-here?lq=1) – Bo Persson Aug 10 '12 at 11:39
  • 1
    Is there any reason why you cannot use `template std::ostream& operator << (std::ostream&, const Test&);`? – juanchopanza Aug 10 '12 at 11:42

1 Answers1

4

In typename Test<T>::unspecified, T is in a non-deducible context, since it appears to the left of a ::. Thus your function template is never even considered, and the conversion to unspecified is used as the sole viable overload.

The short answer is simply that "templates don't work like that". Let me know if you want a longer answer.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Yeah, sorry... No i don't need long answer. – ForEveR Aug 10 '12 at 11:40
  • Wouldn't it be more accurate to say: "the actual parameter type is to the **right** of a `::`, which prevents the template argument `T` to the left of the `::` from being deduced."? I.e. the obstruction is that nested types do not participate in argument deduction. – TemplateRex Aug 10 '12 at 12:04