Синтаксис шаблона в C ++ - PullRequest
2 голосов
/ 13 мая 2010

Я действительно не понимаю шаблоны и пытался выполнить простой поиск минимума для целых, двойных чисел и символов.

Первый вопрос, почему иногда используется template<typename T>, а иногда template<>?

Второй вопрос, я не знаю, что я делаю не так со следующим кодом:

#include <iostream>

template <typename T>
T minimum(T arg1, T arg2)
{
    return arg1 < arg2 ? arg1 : arg2;
}

template <typename T>
// first I tried template <> instd of above, but wasn't sure the difference
T minimum<const char *>(const char *arg1, const char *arg2)
{
    return strcmp(arg1, arg2) ? arg2 : arg1;
}

int main()
{
    std::cout << minimum<int>(4, 2) << '\n';
    std::cout << minimum<double>(2.2, -56.7) << '\n';
    std::cout << minimum(2.2, 2) << '\n';
}

Compile Errors:
 error C2768: 'minimum' : illegal use of explicit template arguments
 error C2783: 'T minimum(const char *,const char *)' : could not deduce template argument for 'T'
 : see declaration of 'minimum'
 : error C2782: 'T minimum(T,T)' : template parameter 'T' is ambiguous
 : see declaration of 'minimum'

В-третьих, при знакомстве с разделением файлов .h и .cpp, если бы я хотел, чтобы эта функция minimal () была статической функцией моего класса, но это была единственная функция в этом классе, я должен был бы иметь шаблонный класс? Первоначально я попытался сделать это таким образом, вместо того, чтобы хранить все это в одном файле, и у меня также возникли некоторые ошибки компиляции, которые я не могу вспомнить прямо сейчас, и не был уверен, как я это сделаю. Спасибо!

Ответы [ 5 ]

6 голосов
/ 13 мая 2010

Похоже, вам нужно (и изучить) книгу шаблонов обложек - похоже, вам нужно изучить слишком много основ, чтобы покрыть ответ здесь.

Синтаксис template<> используется для специализации шаблонов. Для того, что вы, очевидно, хотите, вы бы сделали что-то вроде этого:

template <class T>
T minimum(T const &a, T const &b) {
    return a < b ? a : b;
}

template<>
char const *minimum<char const *>(char const *a, char const *b) { 
    return strcmp(a, b) ? a : b;
}

В общем, однако, это действительно неправильная вещь - вместо предоставления специализаций для char const *, вы обычно хотите просто использовать std::string, что обеспечивает operator< Ваша первая версия будет работать.

3 голосов
/ 13 мая 2010

Похоже, на ваш вопрос почти дан ответ, но у вас все еще есть пара нерешенных вопросов ...

std::cout << minimum(2.2, 2) << '\n';

Это не скомпилируется с двумя предоставленными вами шаблонными функциями, так как не существует соответствующей функции для вызова minimum(double, int). Это оставляет вам два варианта:

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

template <typename T, typename U>
T minimum(T arg1, U arg2)
{
    return arg1 < arg2 ? arg1 : arg2;
}

или

Вы можете изменить свой код, чтобы указать, какую специализацию вызывать:

std::cout << minimum<double>(2.2, 2) << '\n';

Существует также ошибка в вашей специализации const char* (после устранения синтаксической ошибки), поскольку нулевое возвращаемое значение из strcmp указывает, что обе строки равны. Следующее утверждение не будет выполнено:

assert(0 == strcmp("aaa", minimum("aaa", "bbb")));

Это можно исправить так:

template <>
const char* minimum<const char*>(const char* arg1, const char* arg2)
{
    return strcmp(arg1, arg2) > 0 ? arg2 : arg1;
}
2 голосов
/ 13 мая 2010

Давайте ответим на этот первый вопрос. Вы хотите просмотреть специализацию шаблона, и это был ваш синтаксис, который был выключен:

#include <iostream>

template <typename T>
T minimum(T arg1, T arg2)
{
    return arg1 < arg2 ? arg1 : arg2;
}

template<> const char * minimum<const char *>(const char *arg1, const char *arg2)
{
    return strcmp(arg1, arg2) ? arg2 : arg1;
}

int main()
{
    std::cout << minimum<int>(4, 2) << '\n';
    std::cout << minimum<double>(2.2, -56.7) << '\n';
    std::cout << minimum(2.2, 2.0) << '\n';
}

Как только вы обернетесь вокруг этого, держу пари, вы можете заставить остальных работать.

2 голосов
/ 13 мая 2010

Попробуйте это:

template <>
const char* minimum<const char *>(const char *arg1, const char *arg2)
{
    return strcmp(arg1, arg2) ? arg2 : arg1;
}
1 голос
/ 13 мая 2010

Ваша специализация const char * неверна. Он возвращает любой тип T. Это не поддерживается вашей функцией, которая возвращает const char *. По сути, вы не можете наполовину выполнить специализацию, либо T специализирована, либо нет. Если он специализированный, то он не должен появляться в списке шаблонов <>. Если он не специализированный, он должен быть в списке шаблонов.

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