Компилятор путает имя (несвязанного) шаблона с именем метода

У меня есть ошибка компиляции в следующем коде. Кажется, что компилятор интерпретирует метод класса set как шаблон, который — на первый взгляд — совершенно не связан с моим кодом.

#include <cassert>
#include <limits>

using namespace std;

template <class T>
class ReduceScalar{

public:
T get() { return *r; };
void set(T t) { *r = t; };
void set(T* t) { r = t; };

private:
T* r;

};

template <class T>
class ReduceSum : public ReduceScalar<T>
{
public:
ReduceSum(T* target) { set(target); set(0); } // COMPILE ERROR};

Компилятор выдает следующую ошибку:

../test/../io/scalarreducers.h:34:26: error: use of class template 'set' requires template arguments
ReduceSum(T* target) { set(target); set(0); }

Но я думаю, что это потому, что он думает, что set это шаблон:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tree:685:71: note: template is declared here
template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;

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

1

Решение

У вас все еще будут проблемы, даже если вы избавитесь от этого неприятного using namespace std, Проблема в том, что функция-член set может существовать не во всех случаях. Код в вопросе использует set как неквалифицированное, независимое имя. Это означает две вещи:

  • Компилятор попытается решить set в точке, где шаблон определен.
  • Компилятор не будет смотреть в базовый класс ReduceScalar<T> для функции-члена set, Это не может быть, потому что этот член может существовать не для всех экземпляров.

Конечный результат: код не компилируется. Решение состоит в том, чтобы превратить это независимое имя в зависимое имя. Это откладывает разрешение зависимых имен до момента создания шаблона. Один из способов сделать это — явно использовать this (которое является зависимым именем).

template <class T>
class ReduceSum : public ReduceScalar<T>
{
public:
ReduceSum(T* target) { this->set(target); }
};

В качестве альтернативы вы можете использовать объявление using (сильно отличающееся от директивы using):

template <class T>
class ReduceSum : public ReduceScalar<T>
{
public:
using ReduceScalar<T>::set;
ReduceSum(T* target) { set(target); }
};
6

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector