Как выполнить несколько различных наборов инструкций для типа данных строки в шаблоне? - PullRequest
3 голосов
/ 08 июля 2011

У меня есть функция-член в классе, которая вызывается для всех bool, double, int и string.Я хочу выполнить несколько инструкций, которые являются общими для всех вышеупомянутых типов данных.Но для String последние несколько строк кода отличаются.Так что любой может предложить мне лучший способ выполнить это в той же функции шаблона.

template< class T>

xyz (t* a)

{
       //few lines are common for all types for data

       //last 3 lines of code is different for Strings
}

Ответы [ 4 ]

3 голосов
/ 08 июля 2011

Решением, как часто, является факторизация общего поведения и предоставление средства для специализации некоторых частей алгоритма (см. Шаблон Шаблонный метод ).

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

template <class T>
void xyz(T * a)
{
    //few lines are common for all types for data

    xyz_finish(a);
}

template <class T>
void xyz_finish(T * a)
{
    // default case (can be empty)
}

void xyz_finish(std::string * s)
{
    // string case
}

Конечно, ваша функция должна иметь более описательное имя, чем та, которую я использовал ...

Вы также можете выполнить симметричную операцию: переместить обычное поведение в функцию и перегрузить функцию «верхнего уровня»:

template <class T>
void xyz(T * a)
{
    common_behavior(a);
}

void xyz(std::string * s)
{
    common_behavior(s);

    // code specific to strings
}

template <class T>
void common_behavior(T * a)
{
    //few lines that are common for all types for data
}

Если вы не хотите или не можете создавать другие функции, вы можете проверить тип параметра:

template <class T>
void xyz(T * a)
{
    // common code

    if (is_same<T, std::string>::value)
    {
        //code for strings
    }
}

is_same - это шаблон класса, содержащий значение, которое имеет значение true, если два его параметра имеют одинаковый тип, доступно в TR1, Boost и C ++ 0x. Это решение будет работать, только если код в предложении if действителен для всех типов данных, с которыми вы создаете экземпляр шаблона. Например, если вы используете функцию-член string в блоке if, компиляция завершится неудачно при создании экземпляра функции с другими типами данных, поскольку вы не можете вызвать метод для примитивного типа.

2 голосов
/ 08 июля 2011

Вы можете переместить последние 3 строки в некоторую функцию и использовать перегрузку функций C ++, то есть одну для bool, вторую для int и т. Д., Я думаю.

2 голосов
/ 08 июля 2011
struct Foo {
    template <typename T>
    voud foo (T *) {
        foo ();
    }
    void foo (string *) {
        foo ();
        bar ();
    }
private:
    void foo () {
    }
};

Или

struct Foo {
    template <typename T>
    void foo (T * t) {
        do_foo (t);
    }
    void foo (string * s) {
        do_foo (s);
        bar (s);
    }
private:
    template <typename T>
    void do_foo (T *) {
    }
};

Вы можете явно специализировать Foo :: foo вне класса.

tempalte <> void Foo :: foo (string *) {}

Похоже, что это может быть использовано в коварных целях ...

1 голос
/ 08 июля 2011

Вам нужно только специализировать свой шаблон для строки, как показано ниже:

template<> xyz(string* a) { /* code here, including modified lines */ }

РЕДАКТИРОВАТЬ: По-видимому, я не заметил бит "функция члена" из этого. Решением было бы добавить дополнительную косвенность, функцию, которую вы специализируете на строке и вызываете в конце вашей текущей функции.

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