Переслать объявление функции, которая использует enable_if: неоднозначный вызов - PullRequest
4 голосов
/ 08 января 2010

У меня возникли проблемы с объявлением функции, которая использует 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 типа 'type' соответствует void, когда условие истинно, поэтому, насколько я вижу, две сигнатуры foo совпадают. Почему компилятор считает, что они разные, и есть ли правильный способ пересылки объявлений foo (желательно без повторения части enable_if)?

Ответы [ 2 ]

3 голосов
/ 13 января 2010

Это проблема не только с 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)       
{       
}
1 голос
/ 09 января 2010

Проблема в том, что объявление и определение не совпадают.

Решение состоит в том, что объявление должно содержать точно такую ​​же подпись и бит 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...