шаблон C ++ строки шаблона c ++

Я работал над шаблоном для функции. Для упрощения скажем, что это выглядит так:

template < typename T >
void f(const T & x)
{
cout << "generic case" << endl;
cout << x << endl;
}

Я всегда думал, что C-строки нельзя использовать в качестве аргументов параметров шаблона. Но на самом деле работает следующее (с использованием g ++ 4.5.1):

f("hello world");

Итак, мой вопрос: что T когда я звоню f("hello world")?

Я пытался специализироваться, чтобы увидеть, что именно происходит. Например с char[] является const char* Я посмотрел на это (что, очевидно, не работает):

template < typename T >
void f(const T & x)
{
cout << "generic case" << endl;
cout << x << endl;
}
template <>
void f(const const char * T & x)
{
cout << "char[] case" << endl;
cout << x << endl;
}

и попробовал несколько вариантов. Никто из них не работает.

В сторону: мне не нужно это для того, что я делаю. Мне нужна специализация для случая T = «C-строка», поэтому я просто написал другую функцию шаблона:

template < typename T >
void f(const T & x)
{
cout << "generic case" << endl;
cout << x << endl;
}
template < typename T >
void f(T x[])
{
cout << "T[] case" << endl;
cout << x << endl;
}

Я просто спрашиваю, потому что мне интересно, что именно происходит и почему C-строка может быть аргументом шаблона, когда то, что я прочитал, говорит, что это не может быть. Я, должно быть, что-то неправильно понял / неправильно понял о шаблонах.

3

Решение

Нет типа C-string. Термин C-строка определяет содержание, а не тип. Он относится к части массива символов, в которой где-то есть нулевой символ, который некоторые функции интерпретируют как конец строки.

Что вас действительно интересует, так это строковый литерал. Строковый литерал имеет тип const char[N]где N — количество символов в строке, включая неявный нулевой терминатор. Так "hello world" имеет тип const char[12], Вы можете специализироваться на этом так:

template<>
void f(const char(&x)[12])
{
cout << "const char[12] case" << endl;
cout << x << endl;
}

Обратите внимание, что это касается только массивов размера 12. Однако вы можете перегружать (не специализироваться) f() за все размеры как это:

template<size_t N>
void f(const char(&x)[N])
{
cout << "const char[" << N << "] case" << endl;
cout << x << endl;
}

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

3

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

Обратите внимание, что это также будет работать как const char [N] и const char *, оба будут выводить,

template < typename T >
void f(const T* x)
{
cout << "const char* case" << endl;
cout << x << endl;
}

Специализация здесь — это постоянный тип указателя.

Если вам нужна специализация на основе типов массивов символов или указателей, вы также можете использовать простую перегрузку функций.

0

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