Forward declaring a function that uses enable_if : ambiguous call

ambiguity, c++, enable-if, forward-declaration

Solution

This is not only a problem with enable_if. You get the same error on Visual Studio and gcc with the following code:

struct TypeVoid {
  typedef void type;
};

template<typename T>
void f();

template<typename T>
typename T::type f() {
}

int main()
{
  f<TypeVoid>();
  return 0;
}

I think the main problem is that the return type (before instantiation) is part of the signature of a template function. There is more information here.

Regarding your code, if the declaration refers to the definition, you should match both:

// Declaration       
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);       

// Definition       
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)       
{       
}

If the declaration refers to a different function, the compiler would never be able to choose the correct one for ints, because they both are valid. However, you can disable the first one for ints using disable_if:

// Other function declaration
template <typename T>
typename boost::disable_if<boost::is_same<T, int> >::type foo(T t);

// Defition
template <typename T>       
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)       
{       
}

Problem

I have some trouble forward declaring a function that uses `boost::enable_if`: the following piece of code gives me a compiler error: ``` // Declaration template <typename T> void foo(T t); // Definition template <typename T> typename boost::enable_if<boost::is_same<T, int> >::type foo(T t) { } int main() { foo(12); return 0; } ``` When compiling, I get an "ambiguous call to foo" error. According to the definition of `enable_if`, the 'type' typedef corresponds to `void` when the condition is true, so as far as I can see, the two signatures of `foo` match. Why does the compiler think they are different, and is there a correct way to forward declare `foo` (preferably without repeating the `enable_if` part)?

Original source

Related problems