ошибка «неверное использование неполного типа» с частичной специализацией шаблона - PullRequest
31 голосов
/ 03 октября 2008

следующий код:

template <typename S, typename T>
struct foo {
   void bar();
};

template <typename T>
void foo <int, T>::bar() {
}

дает мне ошибку

invalid use of incomplete type 'struct foo<int, T>'
declaration of 'struct foo<int, T>'

(я использую gcc.) Мой синтаксис для частичной специализации неверен? Обратите внимание, что если я уберу второй аргумент:

template <typename S>
struct foo {
   void bar();
};

template <>
void foo <int>::bar() {
}

тогда компилируется правильно.

Ответы [ 3 ]

37 голосов
/ 03 октября 2008

Вы не можете частично специализировать функцию. Если вы хотите сделать это для функции-члена, вы должны частично специализировать весь шаблон (да, это раздражает). В большом шаблонном классе для частичной специализации функции вам потребуется обходной путь. Возможно, будет работать шаблонная структура члена (например, template <typename U = T> struct Nested). Или же вы можете попробовать извлечь из другого шаблона, который частично специализируется (работает, если вы используете нотацию this->member, в противном случае вы столкнетесь с ошибками компилятора).

7 голосов
/ 19 мая 2014

Хотя Coppro уже упоминал о двух решениях, а Anonymous объяснил второе, мне потребовалось довольно много времени, чтобы понять первое. Возможно, следующий код будет полезен для кого-то, кто наткнулся на этот сайт, который по-прежнему занимает высокое место в Google, как я. Пример (передача вектора / массива / одного элемента numericT в качестве dataT и последующий доступ к нему через [] или напрямую), конечно, несколько надуманный, но он должен проиллюстрировать, как вы можете приблизиться к частичной специализации функции-члена, обернув ее в частично специализированном классе.

/* The following circumvents the impossible partial specialization of 
a member function 
actualClass<dataT,numericalT,1>::access
as well as the non-nonsensical full specialisation of the possibly
very big actualClass. */

//helper:
template <typename dataT, typename numericalT, unsigned int dataDim>
class specialised{
public:
  numericalT& access(dataT& x, const unsigned int index){return x[index];}
};

//partial specialisation:
template <typename dataT, typename numericalT>
class specialised<dataT,numericalT,1>{
public:
  numericalT& access(dataT& x, const unsigned int index){return x;}
};

//your actual class:
template <typename dataT, typename numericalT, unsigned int dataDim>
class actualClass{
private:
  dataT x;
  specialised<dataT,numericalT,dataDim> accessor;
public:
  //... for(int i=0;i<dataDim;++i) ...accessor.access(x,i) ...
};
3 голосов
/ 04 июня 2011

Если вам нужно частично специализировать конструктор, вы можете попробовать что-то вроде:

template <class T, int N>
struct thingBase
{
    //Data members and other stuff.
};

template <class T, int N> struct thing : thingBase<T, N> {};

template <class T> struct thing<T, 42> : thingBase<T, 42>
{
    thing(T * param1, wchar_t * param2)
    {
        //Special construction if N equals 42.
    }
};

Примечание: это было анонимно из-за чего-то, над чем я работаю. Вы также можете использовать это, когда у вас есть шаблонный класс с большим и большим количеством членов, и вы просто хотите добавить функцию.

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