«Нет соответствующего вызова функции» в шаблонной функции - PullRequest
2 голосов
/ 06 июня 2011

Я продолжаю получать следующую ошибку при попытке написать функцию шаблона:

main.cpp|17|error: no matching function for call to ‘dotproduct(vector<float, 3u>&, vector<float, 3u>&)’|

Я искал ошибку и обнаружил некоторые другие случаи, когда нетипичный параметр шаблона мог оказаться проблематичным, еслиПараметр был поплавком или двойным.Я использую шаблонный тип нетипичного типа size_t для определения размера матриц и векторов.

У меня есть следующие классы:

matrix:

template<class element_t, size_t rows, size_t columns>
class matrix
{
private:
  element_t elements_[rows*columns];
  // ...
};

вектор:

template<class element_t, size_t size>
class vector
  : public matrix<element_t, size, 1>
{
  //...
};

моя функция:

template<class vector_t>
typename vector_t::element_t dotproduct(const vector_t &vector0, const vector_t &vector1)
{
  typename vector_t::element_t result_(0);
  for(size_t index_ = 0; index_ < vector_t::rows * vector_t::colums; ++index_){
    result_ += vector0[index_] * vector1[index_];
  }

  return result_;
}

вызывается из:

int main(int count, char *arguments[])
{
  typedef vector<float, 3> vec3;

  vec3 a = {1.0f, 2.0f, 3.0f}, b = {3.0f, 2.0f, 1.0f};

  std::cout << dotproduct(a, b) << std::endl;
  std::cin.get();
}

gcc версии 4.5.2 (Ubuntu / Linaro 4.5.2-8ubuntu4)

1 Ответ

2 голосов
/ 06 июня 2011

Имена параметров шаблона могут использоваться только внутри шаблона класса (или функции), которому соответствует список параметров шаблона.Это имеет смысл - стандарт не дает никаких гарантий относительно имен параметров шаблона;они могут отличаться даже между двумя объявлениями!

Обратите внимание:

template <typename U, typename T>
class A;

template <typename T, typename U>
class A
{ };

int main()
{
  A<int, char>::T some_variable; // which type parameter to use?
}

Поскольку имена параметров шаблона не могут быть использованы, ваш шаблон функции удален из кандидатов на перегрузку, а другие функции отсутствуют, разрешение перегрузки не удается (в основном то, что сказал bluescarni).

Правильный способ справиться с этим - typedef имя шаблона.Как только вы это сделаете, имя станет пригодным для использования даже вне класса / функции (ну, если оно не private).

Чтобы исправить ваш пример, вам необходимо:

template<class Element, size_t rows, size_t columns>
class matrix
{
public:
  typedef Element element_t;
private:
  element_t elements_[rows*columns];
  // ...
};
...