Синтаксис подписи функции шаблона класса

#c

#c

Вопрос:

У меня есть класс, определенный следующим образом:

 template< class TBoundingBox >
class BoundingBoxPlaneCalculator
{
  typedef PlaneSpatialObject< TBoundingBox::PointDimension > PlaneSpatialObjectType;
  typedef typename PlaneSpatialObjectType::Pointer      PlaneSpatialObjectPointer;
  std::vector<PlaneSpatialObjectPointer> GetPlanes() const{}
}
  

Если я вызываю функцию, подобную:

 std::vector<PlaneCalculatorType::PlaneSpatialObjectPointer> planes = planeCalculator->GetPlanes();
  

Это работает нормально. Однако, если я изменю разделение на просто

   std::vector<PlaneSpatialObjectPointer> GetPlanes() const;
  

а затем попытайтесь определить функцию вне заголовка:

 template< class TBoundingBox >
std::vector<BoundingBoxPlaneCalculator< TBoundingBox >::PlaneSpatialObjectPointer>
BoundingBoxPlaneCalculator< TBoundingBox >::GetPlanes() const
{

}
  

Я получаю

 itkBoundingBoxPlaneCalculator.txx:61:82: error: type/value mismatch at argument 1 in template parameter list fortemplate<class _Tp, class _Alloc> class std::vector’
itkBoundingBoxPlaneCalculator.txx:61:82: error:   expected a type, got ‘itk::BoundingBoxPlaneCalculator<TBoundingBox>::PlaneSpatialObjectPointer’
  

Я также пытался добавить typename, но ничего не изменилось:

 template< class TBoundingBox >
std::vector<typename BoundingBoxPlaneCalculator< TBoundingBox >::PlaneSpatialObjectPointer>
BoundingBoxPlaneCalculator< TBoundingBox >::GetPlanes() const
  

Кто-нибудь может увидеть, что не так с этим синтаксисом?

Спасибо,

Дэвид

Комментарии:

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

2. Что такое TBoundingBox::PointDimension ? Тип? Целое число? Если это тип, я продолжаю задаваться вопросом, почему вам не нужен typename перед этим… И какой компилятор вы используете?

Ответ №1:

Я в значительной степени скопировал ваш код, но использовал int для замены типа, который вы не определяли, и у меня это отлично работает (используя g 4.4):

 #include <vector>

template<class TBoundingBox>
class BoundingBoxPlaneCalculator
{
public:
    typedef int* PlaneSpatialObjectPointer;
    std::vector<PlaneSpatialObjectPointer> GetPlanes() const;
};

template<class TBoundingBox>
std::vector<typename BoundingBoxPlaneCalculator<TBoundingBox>::PlaneSpatialObjectPointer>
    BoundingBoxPlaneCalculator<TBoundingBox>::GetPlanes() const {}

int main()
{
    BoundingBoxPlaneCalculator<int> planeCalculator;
    planeCalculator.GetPlanes();
}
  

Дело в том, что это не выглядит действительно отличающимся от того, что вы опубликовали, за исключением того факта, что PlaneSpatialObjectPointer не было объявлено в вашем коде. Итак, либо где-то в вашем реальном коде есть опечатка или недостающий фрагмент, либо происходит что-то еще.

Комментарии:

1. Я использую gcc 4.6. Я пытаюсь свести проблему к отдельному, компилируемому примеру.

2. Интересно, может ли тогда помочь добавление typename перед этим? Я не знаю, я не очень хорошо знаком с MSVC и особенно не с этой предполагаемой ошибкой (есть ссылка?).

3. Забудьте мой комментарий, OP не использует MSVC, и даже MSVC (по крайней мере, 2010) блокируется, когда PointDimension является типом.

4. Я попытался упростить проблему, чтобы она была самостоятельной. Я не знаю, правильно ли я понял, но новые ошибки таковы: аргумент шаблона 1 недопустим в строке std::vector<> в main()

5. Чья функция main(), ваша или моя? Работает ли мой код для вас или нет? Если нет, пожалуйста, вставьте полную ошибку компилятора.

Ответ №2:

Похоже, мне просто пришлось добавить typename в вызывающую функцию:

 std::vector<typename PlaneCalculatorType::PlaneSpatialObjectPointer> planes = planeCalculator->GetPlanes();
  

Я в замешательстве, почему это работало без этого, когда функция была определена внутри класса??