Вперед объявить функцию, которая использует включить, если: неоднозначный вызов
У меня есть некоторые проблемы с объявлением функции, которая использует boost::enable_if
: следующий фрагмент кода выдает ошибку компилятора:
// 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;
}
При компиляции я получаю ошибку "неоднозначный вызов foo". Согласно определению enable_if
, тип typedef соответствует void
, когда условие истинно, так что, насколько я могу видеть, две сигнатуры foo
совпадают. Почему компилятор думает, что они разные, и есть ли правильный способ переадресации declare foo
(предпочтительно без повторения части enable_if
)?
2 ответа:
Это не только проблема с enable_if. Вы получаете ту же ошибку в Visual Studio и gcc со следующим кодом:
struct TypeVoid { typedef void type; }; template<typename T> void f(); template<typename T> typename T::type f() { } int main() { f<TypeVoid>(); return 0; }
Я думаю, что основная проблема заключается в том, что возвращаемый тип (до создания экземпляра) является частью сигнатуры функции шаблона. Здесь больше информации .
Что касается вашего кода, если объявление ссылается на определение, вы должны соответствовать обоим:
// 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) { }
Если объявление ссылается на другую функцию, компилятор никогда не будет будьте в состоянии выбрать правильный для int s, потому что они оба действительны. Однако вы можете отключить первый для int s, используя 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) { }
Проблема заключается в том, что объявление и определение не совпадают.
Решение состоит в том, что объявление должно содержать точно такую же подпись и бит
enable_if
.#include <boost/type_traits/is_same.hpp> #include <boost/utility/enable_if.hpp> // 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) { } int main() { foo(12); return 0; }
Это прекрасно компилируется на VC2008.