Как заставить эту специализированную функцию работать - PullRequest
0 голосов
/ 20 марта 2011

Вот сделка.Я посмотрел на этом форуме, и я не нашел информацию, которую я ищу, или я, вероятно, не могу повторить ее для моей проблемы.У меня есть класс Table, который является универсальным, и у меня есть класс с именем MyString.

template <typename typeGen, int DIM>
class Table {
    public:
        TableauGenerique() : index_(0) { //On initialise courant à 0
        }
        void add(typeGen type);
    private:
        typeGen tableGen_[DIM];
        int index_;    
};

Моя проблема с функцией добавления.Иногда мне приходится делать это в main.cpp: (который хорошо работает)

 Table <float,6> tabFloat;
    tabFloat.add(1.6564);

, и в какой-то момент мне нужно сделать это, что не работает, потому что мне нужно специализировать функцию add длясоздайте объект MyString, передайте ему строку и затем сохраните объект в массиве (tableGen):

TableauGenerique <MyString,4> tabString;

Итак, я попробовал это (после класса), но безуспешно.

template <typename typeGen, int DIM>
void Table<typeGen,DIM>::add(typeGen type){ //Which is the generic one for float or ints
    if(index_ < DIM) {
        tableGen_[courant_] = type;
        index_++; 
    }
}

template <class typeGen, int DIM>
void Table<typeGen,DIM>::add<string>(typeGen type) { //(line 75) Which is the specific or specialized function for myString
    MyString str(type);
    if(index_ < DIM) {
        tableGen_[courant_] = str;
        index_++; 
    }
}

Итак, как я могу заставить эту работу работать, потому что она вообще не компилируется, говоря: line75: error: ожидаемый инициализатор перед токеном «<» и в основном он говорит, что не соответствует функция для вызова Table :: add (const char [6]), </p>

Надеюсь, все достаточно ясно.Дайте мне знать, если что-то неясно.

Большое спасибо за вашу помощь!

Ответы [ 3 ]

2 голосов
/ 20 марта 2011
template <class typeGen, int DIM>
void Table<typeGen,DIM>::add<string>(typeGen type)

Вы пытаетесь специализировать add(), хотя на самом деле это не шаблон функции для начала. Как вы ожидаете, что это будет работать?


Вы, вероятно, имели в виду: (специализация класса)

template <int DIM>
void Table<string,DIM>::add(string type)

Но тогда это разрешено, только если вы специализируете сам класс. Без специализации класса приведенный выше код выдаст ошибку компиляции!

EDIT:

Вы можете прочитать эти онлайн-уроки:

0 голосов
/ 21 марта 2011

РЕДАКТИРОВАТЬ: После второй мысли, мое предложение ниже в основном эквивалентно

Table<MyString,4> tabString;
tabString.add(MyString("whatever"));

и, следовательно, чрезмерно и / или не решает проблему. Не стесняйтесь игнорировать:)


Я бы расширил класс Table универсальным методом, добавив что-то, из чего можно построить объект нужного типа:

template <typename typeGen, int DIM>
class Table {
    public:
        Table() : index_(0) {}
        void add(typeGen type);
        // The additional method
        template<typename T> void add(const T& src);
    private:
        typeGen tableGen_[DIM];
        int index_;
};

template<typename typeGen, int DIM>
template<typename T>
void Table<typeGen,DIM>::add(const T& src) {
    if(index_ < DIM) {
        tableGen_[courant_] = typeGen(src);
        index_++;
    }
}

Обратите внимание на создание временного объекта typeGen перед назначением. Предполагая, что объект MyString может быть создан из строкового литерала, то есть из const char *, вы можете использовать его следующим образом:

Table<MyString,4> tabString;
tabString.add("whatever");

или если вышеприведенное предположение неверно, вероятно, должно работать следующее (поскольку вы создали экземпляр MyString из экземпляра строки):

tabString.add(string("whatever"));
0 голосов
/ 20 марта 2011

Если вы можете управлять кодом класса MyString, вы можете предоставить конструкторы, которые действуют как неявные преобразования из float в MyString.Пример:

#include <string>
#include <sstream>
#include <iostream>

class MyString {
public:
  MyString(float number) {
    std::stringstream buffer;
    buffer << number;
    value = buffer.str();
  }

  void print() {
    std::cout << value << std::endl;
  }
private:
  std::string value;
};

template <class T>
class Foo {
public:
  void DoStuff(T item) {
    item.print();
  }
};

int main() {
  Foo<MyString> foo;

  foo.DoStuff(1.342); // implicitly converts float to MyString

  return 0;
}

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

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