Yet another template issue ! I'm trying to get a template method that will output an object if it has an overload for the operator <<.
I have pretty much everything working, and implemented an enable\_if in order to make g++ choose the intended specialization for each type of objects.

Thing is, with a non-overloaded object, it works quite fine. But with an overloaded one, both of my specialization are reasonable choices for g++, and instead of compiling it outputs me an ambiguous overload error.

Here's the code :

```
template<typename T>
  static void   Print(Stream& out, T& param, typename enable_if<CanPrint<T>::value>::type = 0)
  {
    out << param;
  }

  template<typename T>
  static void   Print(Stream& out, T& param)
  {
    out << "/!\\" << typeid(param).name() << " does not have any overload for <<.\n";
  }

```

I understand why such a thing is ambiguous. Yet I can't think of a way to make it more obvious... how do I make the compiler understand that the second overload is to be chosen only when the first cannot be ?
['https://Stackoverflow.com/questions/6394968', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/538377/']
You'll get the ambiguity because in both cases you have a function that takes a stream followed by your type `T` as the first two arguments. This works though:

```
#include <iostream>
#include <boost/utility/enable_if.hpp>
#include <typeinfo>

template <class T>
struct CanPrint { enum { value = 0 }; };

template <>
struct CanPrint<int> { enum { value = 1 }; };

template<typename T>
typename boost::enable_if<CanPrint<T>, void>::type 
    Print(std::ostream& out, T& param)
{
    out << param << std::endl;
}

template<typename T>
typename boost::disable_if<CanPrint<T>, void>::type 
    Print(std::ostream& out, T& param)
{
    out << "/!\\" << typeid(param).name() << " does not have any overload for <<.\n";
}

int main()
{
    int i = 1;
    double d = 2;

    Print(std::cout, i);
    Print(std::cout, d);
}

```
The ambiguity is because of the default parameter value.

Calling `Print(stream, whatever)` can be resolved to either the first version with the default third parameter or the second version with no third parameter.

Remove the default value, and the compiler will understand. Otherwise both of them can be chosen always.